Create Bank Payment Intent
The Create Bank Payment Intent API enables seamless fiat-to-stablecoin transfers through traditional banking rails. This feature is perfect for onboarding users from traditional banking to crypto, supporting ACH, Wire, and SEPA payment methods for converting fiat currencies to stablecoins across multiple blockchain networks.
API EndpointCopied!
POST /api/v0/payment-intents/bank
AuthenticationCopied!
All requests require API key authentication using the following headers:
-
x-client-key
: Your application's client key -
x-client-secret
: Your application's client secret
IdempotencyCopied!
The endpoint supports idempotency to prevent duplicate payments:
-
idempotency-key
: Include a unique UUID v4 in the header -
Subsequent requests with the same key return the original response
-
Keys expire after 24 hours
Supported Payment RailsCopied!
Our platform currently supports the following banking payment methods:
Payment Rail |
Code |
Description |
Processing Time |
Supported Regions |
---|---|---|---|---|
ACH Push |
|
US bank transfers (standard) |
1-3 business days |
United States |
ACH Same Day |
|
US bank transfers (same-day) |
Same business day |
United States |
Wire Transfer |
|
International wire transfers |
Same day - 1 business day |
Global |
SEPA |
|
European bank transfers |
1-2 business days |
European Union |
SWIFT |
|
International SWIFT transfers |
1-5 business days |
Global |
SPEI |
|
Mexican instant transfers |
Real-time |
Mexico |
Supported Source CurrenciesCopied!
Currency |
Code |
Description |
Compatible Payment Rails |
---|---|---|---|
USD |
|
US Dollar |
|
EUR |
|
Euro |
|
MXN |
|
Mexican Peso |
|
Supported Destination NetworksCopied!
Network |
Code |
Description |
---|---|---|
Ethereum |
|
Main Ethereum network |
Polygon |
|
Polygon (Matic) network |
Solana |
|
Solana blockchain |
Base |
|
Coinbase's Base network |
Arbitrum |
|
Arbitrum Layer 2 |
Optimism |
|
Optimism Layer 2 |
Avalanche C-Chain |
|
Avalanche C-Chain |
Stellar |
|
Stellar network |
Tron |
|
Tron blockchain |
Supported Destination StablecoinsCopied!
Currency |
Code |
Description |
---|---|---|
USDC |
|
USD Coin |
EURC |
|
Euro Coin |
Request ParametersCopied!
Required Parameters
Parameter |
Type |
Description |
---|---|---|
|
|
The banking payment method to use for the transfer |
|
|
The stablecoin currency to convert TO ( |
|
|
The blockchain network where stablecoin will be delivered |
Optional Parameters
Parameter |
Type |
Description |
---|---|---|
|
|
The fiat currency to convert FROM (defaults to |
|
|
Wallet address for receiving funds (Ethereum 0x... or Solana format) |
|
|
Payment amount in source currency (omit for flexible amounts) |
|
|
Customer's first name (max 100 chars) |
|
|
Customer's last name (max 100 chars) |
|
|
Customer's email address |
|
|
Customer's physical address |
|
|
Customer's country |
|
|
Customer's country ISO code |
|
|
Customer's province/state |
|
|
Customer's province/state ISO code |
|
|
Customer's phone number |
Payment Rail Specific Parameters
ACH Transfers
Parameter |
Type |
Description |
---|---|---|
|
|
Reference for ACH transfers (max 10 chars, alphanumeric + spaces) |
Wire Transfers
Parameter |
Type |
Description |
---|---|---|
|
|
Message for wire transfers (max 256 chars) |
SEPA Transfers
Parameter |
Type |
Description |
---|---|---|
|
|
Reference for SEPA transfers (6-140 chars, specific character set) |
ExamplesCopied!
1. USD Bank to USDC Conversion (ACH)
Convert $1000 USD from US bank account to USDC on Ethereum:
curl -X POST https://api.devdraft.ai/api/v0/payment-intents/bank \
-H "Content-Type: application/json" \
-H "x-client-key: your-client-key" \
-H "x-client-secret: your-client-secret" \
-H "idempotency-key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{
"sourcePaymentRail": "ach_push",
"sourceCurrency": "usd",
"destinationCurrency": "usdc",
"destinationNetwork": "ethereum",
"destinationAddress": "0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1",
"amount": "1000.00",
"customer_first_name": "John",
"customer_last_name": "Doe",
"customer_email": "john.doe@example.com",
"customer_address": "123 Main St, New York, NY 10001",
"customer_country": "United States",
"phoneNumber": "+1-555-123-4567",
"ach_reference": "INV12345"
}'
2. EUR SEPA to EURC Conversion
Convert €500 EUR from European bank account to EURC on Polygon:
curl -X POST https://api.devdraft.ai/api/v0/payment-intents/bank \
-H "Content-Type: application/json" \
-H "x-client-key: your-client-key" \
-H "x-client-secret: your-client-secret" \
-H "idempotency-key: 550e8400-e29b-41d4-a716-446655440001" \
-d '{
"sourcePaymentRail": "sepa",
"sourceCurrency": "eur",
"destinationCurrency": "eurc",
"destinationNetwork": "polygon",
"destinationAddress": "0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1",
"amount": "500.00",
"customer_first_name": "Marie",
"customer_last_name": "Dubois",
"customer_email": "marie.dubois@example.com",
"customer_address": "45 Rue de la Paix, 75002 Paris",
"customer_country": "France",
"phoneNumber": "+33-1-23-45-67-89",
"sepa_reference": "REF-123456789"
}'
3. USD to USDC on Solana (Wire Transfer)
Convert $5000 USD via wire transfer to USDC on Solana:
curl -X POST https://api.devdraft.ai/api/v0/payment-intents/bank \
-H "Content-Type: application/json" \
-H "x-client-key: your-client-key" \
-H "x-client-secret: your-client-secret" \
-H "idempotency-key: 550e8400-e29b-41d4-a716-446655440002" \
-d '{
"sourcePaymentRail": "wire",
"sourceCurrency": "usd",
"destinationCurrency": "usdc",
"destinationNetwork": "solana",
"destinationAddress": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
"amount": "5000.00",
"customer_email": "customer@example.com",
"wire_message": "Investment funds transfer"
}'
4. Flexible Amount Payment Intent
Create a payment intent where users specify the amount during checkout:
curl -X POST https://api.devdraft.ai/api/v0/payment-intents/bank \
-H "Content-Type: application/json" \
-H "x-client-key: your-client-key" \
-H "x-client-secret: your-client-secret" \
-H "idempotency-key: 550e8400-e29b-41d4-a716-446655440003" \
-d '{
"sourcePaymentRail": "ach_push",
"sourceCurrency": "usd",
"destinationCurrency": "usdc",
"destinationNetwork": "polygon",
"destinationAddress": "0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1",
"customer_email": "customer@example.com"
}'
5. Mexican Peso SPEI Transfer
Convert MXN via SPEI to USDC on Base:
curl -X POST https://api.devdraft.ai/api/v0/payment-intents/bank \
-H "Content-Type: application/json" \
-H "x-client-key: your-client-key" \
-H "x-client-secret: your-client-secret" \
-H "idempotency-key: 550e8400-e29b-41d4-a716-446655440004" \
-d '{
"sourcePaymentRail": "spei",
"sourceCurrency": "mxn",
"destinationCurrency": "usdc",
"destinationNetwork": "base",
"destinationAddress": "0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1",
"amount": "20000.00",
"customer_email": "customer@example.com"
}'
6. Same-Day ACH Transfer
Fast USD to USDC conversion using same-day ACH:
{
"sourcePaymentRail": "ach_same_day",
"sourceCurrency": "usd",
"destinationCurrency": "usdc",
"destinationNetwork": "arbitrum",
"destinationAddress": "0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1",
"amount": "750.00",
"customer_email": "customer@example.com",
"ach_reference": "URGENT123"
}
Response FormatCopied!
Success Response (201 Created)
{
"id": "txn_01HZXK8M9N2P3Q4R5S6T7U8V9W",
"bridge_transfer_id": "transfer_abc123xyz456",
"state": "pending",
"amount": "1000.00",
"source": {
"payment_rail": "ach_push",
"currency": "usd"
},
"destination": {
"payment_rail": "ethereum",
"currency": "usdc",
"to_address": "0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1"
},
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"address": "123 Main St, New York, NY 10001",
"country": "United States",
"phone_number": "+1-555-123-4567"
},
"created_at": "2023-07-01T12:00:00.000Z",
"updated_at": "2023-07-01T12:00:00.000Z"
}
Response Fields
Field |
Type |
Description |
---|---|---|
|
|
Unique transaction identifier in our database |
|
|
External bridge service transfer ID |
|
|
Current state: |
|
|
Payment amount (null for flexible amounts until user specifies) |
|
|
Source payment details (bank information) |
|
|
Destination payment details (blockchain information) |
|
|
Customer information (if provided) |
|
|
Creation timestamp (ISO 8601) |
|
|
Last update timestamp (ISO 8601) |
Error ResponsesCopied!
400 Bad Request
{
"statusCode": 400,
"message": [
"Please select a valid source payment rail",
"Destination currency is required"
],
"error": "Bad Request"
}
401 Unauthorized
{
"statusCode": 401,
"message": "Unauthorized - Invalid API credentials",
"error": "Unauthorized"
}
404 Not Found
{
"statusCode": 404,
"message": "App not found",
"error": "Not Found"
}
409 Conflict (Idempotency)
{
"statusCode": 409,
"message": "Idempotency key already used with different parameters",
"error": "Conflict"
}
Payment Rail CharacteristicsCopied!
ACH Push (ach_push)
-
Processing Time: 1-3 business days
-
Cost: Low
-
Limits: Varies by bank (typically $10K-$100K daily)
-
Best For: Regular transfers, subscription payments
-
Reversibility: Yes (up to 60 days)
ACH Same Day (ach_same_day)
-
Processing Time: Same business day
-
Cost: Medium
-
Limits: Lower than standard ACH
-
Best For: Urgent transfers, time-sensitive payments
-
Reversibility: Yes (limited window)
Wire Transfer (wire)
-
Processing Time: Same day to 1 business day
-
Cost: High
-
Limits: High (varies by institution)
-
Best For: Large transfers, international payments
-
Reversibility: Very limited
SEPA (sepa)
-
Processing Time: 1-2 business days
-
Cost: Low to medium
-
Limits: €1M per transaction (varies by bank)
-
Best For: European transfers, EUR payments
-
Reversibility: Limited (fraud/error cases)
SWIFT (swift)
-
Processing Time: 1-5 business days
-
Cost: High
-
Limits: High (varies by institution)
-
Best For: International transfers, non-SEPA regions
-
Reversibility: Very limited
SPEI (spei)
-
Processing Time: Real-time (24/7)
-
Cost: Low
-
Limits: Varies by bank
-
Best For: Mexican peso transfers, instant payments
-
Reversibility: Very limited
Regional Compliance RequirementsCopied!
United States (ACH)
-
Customer Information: Full name, address required for amounts >$3K
-
AML/KYC: Enhanced due diligence for amounts >$10K
-
Documentation: Bank account verification may be required
European Union (SEPA)
-
Customer Information: Full name and address required
-
GDPR Compliance: Data protection requirements apply
-
Strong Customer Authentication: May be required for certain amounts
Mexico (SPEI)
-
Customer Information: RFC (tax ID) may be required for large amounts
-
Local Regulations: CNBV compliance requirements
-
Documentation: Proof of funds may be required
Fees and LimitsCopied!
Developer Fee
-
Standard Rate: 0.20% of transfer amount
-
Minimum Fee: Varies by payment rail
-
Maximum Fee: Capped based on amount
Network-Specific Considerations
Destination Network |
Gas Fee Estimate |
Confirmation Time |
---|---|---|
Ethereum |
$5-$50 |
1-5 minutes |
Polygon |
$0.01-$0.10 |
30 seconds |
Solana |
$0.00025 |
30 seconds |
Base |
$0.10-$1 |
1-2 minutes |
Arbitrum |
$0.50-$2 |
1-2 minutes |
Optimism |
$0.50-$2 |
1-2 minutes |
Avalanche |
$1-$5 |
1-2 minutes |
Use CasesCopied!
1. Fiat On-Ramp
Enable users to convert traditional bank funds into cryptocurrency for the first time.
2. Recurring Payments
Set up automatic conversion of salary or business income into stablecoins.
3. International Remittances
Facilitate cross-border payments with better rates than traditional remittance services.
4. Business Treasury Management
Allow businesses to convert operational funds into stablecoins for yield generation or payments.
5. DeFi Onboarding
Help users fund DeFi protocols directly from their bank accounts.
6. Payroll Conversion
Enable companies to pay employees in stablecoins while sourcing funds from traditional bank accounts.
Best PracticesCopied!
1. Amount Handling
-
Use string format for amounts to avoid precision issues
-
Validate minimum amounts based on payment rail fees
-
Consider currency conversion rates for cross-currency transfers
2. Error Handling
-
Handle bank rejection scenarios gracefully
-
Implement proper retry logic for network failures
-
Provide clear status updates throughout the transfer process
3. Reference Fields
-
Use descriptive references for ACH transfers (helps with reconciliation)
-
Include order/invoice numbers in wire messages
-
Follow SEPA reference format requirements
Integration ExamplesCopied!
JavaScript/TypeScript
interface CreateBankPaymentIntentRequest {
sourcePaymentRail: 'ach_push' | 'ach_same_day' | 'wire' | 'sepa' | 'swift' | 'spei';
sourceCurrency?: 'usd' | 'eur' | 'mxn';
destinationCurrency: 'usdc' | 'eurc';
destinationNetwork: string;
destinationAddress?: string;
amount?: string;
customer_email?: string;
ach_reference?: string;
wire_message?: string;
sepa_reference?: string;
// ... other customer fields
}
async function createBankPaymentIntent(
data: CreateBankPaymentIntentRequest
): Promise<PaymentIntentResponse> {
const response = await fetch('/api/v0/payment-intents/bank', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-client-key': process.env.CLIENT_KEY!,
'x-client-secret': process.env.CLIENT_SECRET!,
'idempotency-key': crypto.randomUUID(),
},
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
// Example usage for ACH transfer
const achTransfer = await createBankPaymentIntent({
sourcePaymentRail: 'ach_push',
sourceCurrency: 'usd',
destinationCurrency: 'usdc',
destinationNetwork: 'ethereum',
destinationAddress: '0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1',
amount: '1000.00',
customer_email: 'customer@example.com',
ach_reference: 'INV12345'
});
Python
import requests
import uuid
from typing import Optional, Dict, Any
def create_bank_payment_intent(
source_payment_rail: str,
destination_currency: str,
destination_network: str,
source_currency: str = "usd",
destination_address: Optional[str] = None,
amount: Optional[str] = None,
customer_email: Optional[str] = None,
ach_reference: Optional[str] = None,
wire_message: Optional[str] = None,
sepa_reference: Optional[str] = None,
**customer_data
) -> Dict[Any, Any]:
url = "https://api.devdraft.ai/api/v0/payment-intents/bank"
headers = {
"Content-Type": "application/json",
"x-client-key": os.getenv("CLIENT_KEY"),
"x-client-secret": os.getenv("CLIENT_SECRET"),
"idempotency-key": str(uuid.uuid4())
}
payload = {
"sourcePaymentRail": source_payment_rail,
"sourceCurrency": source_currency,
"destinationCurrency": destination_currency,
"destinationNetwork": destination_network,
**({} if destination_address is None else {"destinationAddress": destination_address}),
**({} if amount is None else {"amount": amount}),
**({} if customer_email is None else {"customer_email": customer_email}),
**({} if ach_reference is None else {"ach_reference": ach_reference}),
**({} if wire_message is None else {"wire_message": wire_message}),
**({} if sepa_reference is None else {"sepa_reference": sepa_reference}),
**customer_data
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
# Example usage for SEPA transfer
sepa_transfer = create_bank_payment_intent(
source_payment_rail="sepa",
source_currency="eur",
destination_currency="eurc",
destination_network="polygon",
destination_address="0x742d35Cc6634C0532925a3b8D4C9db96c4b4d8e1",
amount="500.00",
customer_email="customer@example.com",
sepa_reference="REF-123456789"
)
PHP
<?php
function createBankPaymentIntent($data) {
$url = "https://api.devdraft.ai/api/v0/payment-intents/bank";
$headers = [
'Content-Type: application/json',
'x-client-key: ' . $_ENV['CLIENT_KEY'],
'x-client-secret: ' . $_ENV['CLIENT_SECRET'],
'idempotency-key: ' . wp_generate_uuid4()
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 201) {
throw new Exception("HTTP Error: " . $httpCode);
}
return json_decode($response, true);
}
// Example usage for wire transfer
$wireTransfer = createBankPaymentIntent([
'sourcePaymentRail' => 'wire',
'sourceCurrency' => 'usd',
'destinationCurrency' => 'usdc',
'destinationNetwork' => 'solana',
'destinationAddress' => '9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM',
'amount' => '5000.00',
'customer_email' => 'customer@example.com',
'wire_message' => 'Investment funds'
]);
?>
Monitoring and WebhooksCopied!
Transaction States
Monitor payment intent progression through these states:
-
pending
: Payment intent created, awaiting bank transfer -
processing
: Bank transfer received, converting to stablecoin -
completed
: Stablecoin delivered to destination address -
failed
: Transfer failed (insufficient funds, invalid account, etc.) -
cancelled
: Transfer cancelled by user or system
Webhook Events
Set up webhooks to receive real-time updates:
-
payment_intent.created
-
payment_intent.processing
-
payment_intent.completed
-
payment_intent.failed
-
payment_intent.cancelled
SupportCopied!
For additional support or questions about the Create Bank Payment Intent API:
-
Check our API status page for known issues
-
Review the error codes and messages in your responses
-
Contact our support team with your
bridge_transfer_id
for specific transaction issues -
Consult regional compliance guidelines for specific requirements