Payin Integration
What Are Payins and Why They Matter
Payins enable your application to seamlessly accept fiat payments from your customers' bank accounts, which will be converted to cryptocurrency. Whether you're a developer or a business owner, this guide will help you integrate DollarPe's Payin system.
Prerequisites:
- Ensure you have completed the authentication setup
- Configure your webhook endpoint for real-time updates
- Review the following guides to ensure compatibility:
- supported geographies
- supported stablecoins and blockchains
- supported fiat methods
- Verify your users have completed KYC and have at least one verified bank account
Warning: Initiate the payin before the quotation expiry time.
Integration at a Glance
The Payin integration flow for centralized exchanges involves the following key steps:
- Fetch Configurations - Retrieve the basic configuration to understand supported assets, networks, and limits.
- Validate user requirements – Ensure the customer has completed KYC verification and has at least one verified bank account added
- Fetch payin limits – Retrieve payin limits to check daily limits, available limits, and whether Enhanced Due Diligence (EDD) is required.
- Fetch exchange rates – Retrieve the latest cryptocurrency exchange rates
- Create a quotation – Generate a quote for the desired payin amount
- Send fiat payment – Transfer the fiat amount to the provided bank details
- Initiate the payin – Start the payin using the UTR from the fiat payment
- Link exchange transfer ID – Link the exchange transfer ID with the payin.
- Monitor transaction status – Track the progress of the transaction
- Handle completion – Finalize the payin once the transaction is confirmed
Visual Integration Flow
Process Flow Diagram
Sequence Diagram: Detailed Process Flow
Step-by-Step Integration Guide
Step 1: Fetch Configurations
Before starting the integration, fetch the basic configuration to understand supported assets, networks, and limits:
GET /payin/configuration
{
"status": true,
"message": "Success",
"data": {
"inr": {
"supported_assets": [
"usdt",
"usdc"
],
"coin_limits": {
"usdt": {
"imps": {
"min": 28,
"max": 5563
},
"upi": {
"min": 28,
"max": 1113
}
},
"usdc": {
"imps": {
"min": 28,
"max": 5563
},
"upi": {
"min": 28,
"max": 1113
}
}
},
"required_risk_parameters": [
"ip_address",
"device_id",
"suspicious_activity_report",
"law_enforcement_agency_report"
]
}
}
}
Key Fields:
supported_fiats: List of supported fiat currenciessupported_assets: List of supported cryptocurrenciessupported_networks: List of supported blockchain networkscoin_limits: Minimum and maximum limits for each supported cryptocurrency
If you are storing these configurations in your application to validate user inputs and display appropriate options, make sure to update this data periodically.
Step 2: Check Customer KYC and Bank Account status
Before initiating any payin, ensure the customer is KYC-verified and has a verified bank account.
GET /customer/{customer_id}
Response:
{
"status": true,
"message": "Success",
"data": {
"id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"client_reference_id": "client_id_1",
"full_name": "John Doe",
"email": "john@example.com",
"phone": "+911234123412",
"country": "IND",
"type": "INDIVIDUAL",
"status": "UNVERIFIED",
"failure_reason": null
}
}
GET /bank/list/{customer_id}
{
"status": true,
"message": "Success",
"data": {
"count": 1,
"next": null,
"previous": "<url>",
"results": [
{
"id": "4e6f1b20-a73c-11ec-b909-0242ac120002",
"customer_id": "550e8400-e29b-41d4-a716-446655440000",
"account_number": "123456789012",
"ifsc_code": "ABC123456",
"vpa": "testing@upi",
"bank_account_type": "ACCOUNT_DETAILS",
"bank_account_status": "VERIFIED"
}
]
}
}
Step 3: Check Payin Limit
Before creating a quotation, check the customer's available payin limit to ensure they are eligible to create a new order.
GET /payin/limit/{customer_id}
{
"status": true,
"message": "Success",
"data": {
"daily_limit": 20000,
"available_limit": 20000,
"payment_method_limits": {
"per_transaction_limit": {
"UPI": 20000,
"IMPS": 20000
},
"total_available_limit": {
"UPI": 20000,
"IMPS": 20000
}
},
"full_limit_reset_timestamp": "2024-03-13T10:00:00Z",
"is_edd_required": false,
"is_limit_increase_available": true
}
}
Key Fields:
daily_limit: Maximum daily payin limit for the assetavailable_limit: Remaining available payin limit for the current daylimit_reset_timestamp: Unix timestamp when the daily limit will resetis_edd_required: Whether Enhanced Due Diligence (EDD) is required (true or false)is_limit_increase_available: Whether the customer can apply for a higher daily limit
How to use:
- If
is_limit_increase_availableis sufficient for the intended transaction andis_edd_requiredis false, proceed to the next step. - If
is_edd_requiredis true and the limit is not available, direct the user to complete EDD as part of the KYC process before proceeding. After EDD, recheck the limit. - If
is_edd_requiredis false and the limit is not available (i.e., user has already completed EDD and limit is still exhausted), do not allow the user to create a new payin order and show an appropriate error message. No further action is possible until the limit resets.
Step 4: Fetch Exchange Rate
Get the real-time exchange rate for a given crypto asset.
GET /payin/fetch-rate
{
"asset": "usdt",
"fiat": "inr",
}
{
"status": true,
"message": "Success",
"data": {
"asset": "USDT",
"fiat": "INR",
"rate": 87.2
}
}
Key Fields:
asset: Cryptocurrency to be received (e.g., "USDT", "USDC")fiat: Fiat currency to send (e.g., "INR" for Indian Rupee)rate: Current exchange rate (amount of fiat per 1 unit of crypto)
Rates fluctuate constantly based on market conditions. We recommend fetching a new rate before each transaction to ensure accuracy.
Step 5: Create a Quotation
After getting the current rate, create a quotation to lock in the rate.
POST /payin/quotation
{
"asset": "USDC",
"fiat": "INR",
"sending_amount": "10000",
"customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"bank_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"payment_method": "IMPS",
"risk_parameters": {
"ip_address": "127.0.0.1",
"device_id": "",
"suspicious_activity_report": "True",
"law_enforcement_agency_report": "False"
}
}
{
"status": true,
"message": "Success",
"data": {
"id": "da43453c-f854-42ac-9a1e-619b37060bbc",
"customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"bank_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"asset": "USDC",
"fiat": "INR",
"payment_method": "IMPS",
"sending_amount": "10000.00000000",
"rate": "91.91",
"receiving_amount": "108.80",
"quotation_fee": {
"client_fee": "0.00",
"client_fee_usdt": "0.00",
"dollarpe_fee": "0.00",
"pg_fee": "0.00",
"client_gst": "0.00",
"client_gst_usdt": "0.00",
"dollarpe_gst": "0.00",
"pg_gst": "0.00",
"tds": "0",
"gross_effective_exchange_rate": "91.91"
},
"deposit_instructions": {
"account_number": "1234567890",
"ifsc": "1234567890",
"account_name": "Sandbox Technologies Pvt Ltd"
},
"created_at": "2025-04-17T14:10:27.567448+00:00",
"expiry_time": "2025-04-17T14:20:27.566842+00:00"
}
}
Key Fields:
asset: Cryptocurrency to be receivedfiat: Fiat currency to send (e.g., "INR" for Indian Rupee)receiving_amount: Amount in cryptocurrency to receivecustomer_id: ID of the KYC-verified customerbank_id: ID of the verified bank accountbank_details: Bank account details for sending the fiat paymentexpiry_time: Time until the quotation expires
You must complete your transaction before this time expires.
Step 6: Send Fiat Payment
Once you have the quotation and bank details, instruct the customer to send the fiat payment:
- Use the provided bank account details to make the payment
- Ensure the exact amount is sent as specified in the quotation
- Keep the UTR (Unique Transaction Reference) from the bank
- Complete the payment before the quotation expires
Step 7: Initiate the Payin
After the fiat payment is completed, create a payin request with the UTR:
POST /payin/initiate
{
"quotation_id": "2e104290-07c8-49f1-a5ca-0d27f0078f8a",
"customer_id": "def8b740-99f9-4cba-bc9e-99de57e927b4",
"client_reference_id": "testUser123",
"utr": "UTR123456789"
}
{
"status": true,
"message": "Success",
"data": {
"id": "9e67356c-cf5e-4fa2-958f-411e7607a307",
"customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"quotation_id": "da43453c-f854-42ac-9a1e-619b37060bbc",
"client_reference_id": "payin_first_test_3",
"utr": "ICICRC20250110C9876546",
"status": "PROCESSING",
"created_at": "2025-04-17T14:11:35.504428Z",
"asset": "USDC",
"fiat": "INR",
"payment_method": "IMPS",
"sending_amount": 10000.0,
"dollarpe_rate": 91.91,
"receiving_amount": 108.8,
"deposit_instructions": {
"ifsc": "1234567890",
"account_number": "1234567890",
"account_name": "Sandbox Technologies Pvt Ltd"
},
"fees": {
"client_fee": 0.0,
"client_fee_usdt": 0.0,
"dollarpe_fee": 0.0,
"pg_fee": 0.0,
"client_gst": 0.0,
"client_gst_usdt": 0.0,
"dollarpe_gst": 0.0,
"pg_gst": 0.0,
"tds": 0.0,
"gross_effective_exchange_rate": 91.91
}
}
}
Key Fields:
quotation_id: ID received from Step 3customer_id: ID of the KYC-verified customerclient_reference_id: Your internal reference ID for tracking (optional)bank_id: ID of the verified bank accountutr: Unique Transaction Reference from the bank paymentstatus: Current status of the payin
Step 8: Monitor Transaction Status
After initiating the payin, you need to track the payin status. There are two ways to monitor this status:
Option A: Webhook Integration (Recommended)
Webhooks provide real-time updates about payin status changes. Configure your webhook endpoint to receive these notifications:
// Sample webhook payload for payin status updates
{
"type": "PAYIN",
"id": "ac7c5360-0b57-4fb7-88f2-df1c371930ee",
"event": "COMPLETED", // or "FAILED", "PROCESSING"
"failure_reason": null, // Contains failure reason if status is "FAILED"
"timestamp": "2025-03-21T13:37:53.208137Z",
"metadata": {}
}
If using webhooks, ensure your server acknowledges receipt with a 200 OK response to prevent duplicate notifications.
Option B: Status Polling
If webhooks aren't feasible, you can periodically check the status using the payin endpoint:
GET /payin/{payin_id}
{
"status": true,
"message": "Success",
"data": {
"id": "ac7c5360-0b57-4fb7-88f2-df1c371930ee",
"quotation_id": "c9f343b5-ff56-4d52-93af-0962f75242b7",
"customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
"client_reference_id": "payin_first_test",
"bank_id": "c863b696-7fbd-4b16-b3a7-134aefffb2fe",
"asset": "USDT",
"network": "BSC",
"fiat": "INR",
"sending_amount": "858.96000000",
"rate": "87.20000000",
"receiving_amount": "10.00000000",
"fees": {
"client_fee": "",
"dollarpe_fee": "",
"pg_fee": "",
"client_gst": "",
"dollarpe_gst": "",
"pg_gst": "",
"tds": "",
"gross_exchange_rate": ""
},
"utr": "123456789012",
"status": "PROCESSING",
"failure_reason": "",
"created_at": "2025-03-21T13:37:53.208137Z",
"updated_at": "2025-03-21T13:37:53.208142Z"
}
}
If using the polling approach, we recommend checking no more frequently than once every 60 seconds to avoid API rate limits.
Possible Status Values:
PROCESSING: Initial state, waiting for payment verificationSUCCESS: Payin has been successfully completedFAILED: Payin has failed and failure_reason is updated
Step 9: Handle Transaction Completion
Successful Transactions
When a payin is completed successfully:
- Update your internal records with the transaction details
- Credit the cryptocurrency to your user's account
- Notify your user that the funds have been received
- Store the transaction details for future reference and customer support
Step 10: Link Exchange Order ID with Exchange Transfer ID
Upon successful payin, ensure the exchange transfer ID (associated with the sent cryptocurrency) is linked to the corresponding exchange order ID.
PATCH /payin/update-transfer-id
{
"payin_id": "c9f343b5-ff56-4d52-93af-0962f75242b7",
"exchange_transfer_id": "9282391023212"
}
{
"status": true,
"message": "Success",
"data": {
"payin_id": "c9f343b5-ff56-4d52-93af-0962f75242b7",
"exchange_transfer_id": "9282391023212"
}
}
Testing Your Integration
Sandbox Environment
Before going live, test your integration thoroughly in our sandbox environment:
- Use the base URL:
https://sandbox-api.dollarpe.xyz - Follow the same steps as production
- Test both successful and failed transaction scenarios
In the sandbox environment, you can simulate different failure scenarios by using specific test values. Refer to our Sandbox Testing Guide for details.
Getting Help
If you encounter any issues with your payin integration:
- Check our API documentation for detailed endpoint information
- Visit the Troubleshooting Guide for common solutions
- Contact our support team with your customer_id and transaction logs
Our support team is available 24/7 to help with integration issues. For urgent matters, use the in-app chat or call our technical support hotline.