The Wallet Top-Up API lets you programmatically add funds to a customer’s wallet balance by initiating payment collection, and configure automatic top-up rules that trigger when the balance drops below a threshold.
Manual Top-Up
Initiate a Top-Up
curl -X POST https://coreapi.io/api/wallet/top-up \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"amount": 100.00,
"currencyCode": "EUR"
}'
Response (201 Created):
{
"id": "top_abc123",
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"requestedAmount": { "amount": 10000, "currencyCode": "EUR" },
"creditedAmount": null,
"status": "pending",
"paymentMethodId": null,
"createdAt": "2026-03-08T10:00:00Z",
"completedAt": null
}
| Field | Type | Required | Description |
|---|
customerId | string | Yes | Customer UUID |
amount | number | Yes | Top-up amount (e.g. 100.00) |
currencyCode | string | Yes | ISO 4217 currency code (e.g. EUR) |
paymentMethodId | string | No | Specific payment method UUID. Defaults to customer’s default payment method |
The top-up creates a PaymentIntent that collects the funds. Once the payment succeeds, the amount is credited to the customer’s wallet.
List Top-Ups
curl https://coreapi.io/api/wallet/top-ups?customerId=CUSTOMER_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Response (200 OK):
{
"items": [
{
"id": "top_abc123",
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"requestedAmount": { "amount": 10000, "currencyCode": "EUR" },
"creditedAmount": { "amount": 10000, "currencyCode": "EUR" },
"status": "completed",
"paymentMethodId": null,
"failureReason": null,
"createdAt": "2026-03-08T10:00:00Z",
"completedAt": "2026-03-08T10:01:00Z"
}
],
"count": 1
}
Top-Up Status
| Status | Description |
|---|
pending | Payment initiated, awaiting completion |
completed | Payment succeeded, balance credited |
failed | Payment failed, no balance change |
Get a Single Top-Up
curl https://coreapi.io/api/wallet/top-ups/TOP_UP_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Auto Top-Up Rules
Auto top-up rules automatically initiate a top-up when a customer’s wallet balance drops below a configured threshold.
Create a Rule
curl -X POST https://coreapi.io/api/wallet/auto-top-up \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"currencyCode": "EUR",
"thresholdAmount": 10.00,
"topUpAmount": 100.00
}'
Response (201 Created):
{
"id": "atr_xyz789",
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"currencyCode": "EUR",
"thresholdAmount": 10.00,
"topUpAmount": 100.00,
"paymentMethodId": null,
"enabled": true,
"consecutiveFailures": 0,
"createdAt": "2026-03-08T10:00:00Z",
"updatedAt": "2026-03-08T10:00:00Z"
}
| Field | Type | Required | Description |
|---|
customerId | string | Yes | Customer UUID |
currencyCode | string | Yes | ISO 4217 currency code |
thresholdAmount | number | Yes | Balance threshold that triggers auto top-up (must be > 0) |
topUpAmount | number | Yes | Amount to top up (must be > 0) |
paymentMethodId | string | No | Specific payment method. Defaults to customer’s default |
Only one rule per customer per currency is allowed. Attempting to create a duplicate returns 400 Bad Request.
List Rules
curl https://coreapi.io/api/wallet/auto-top-up?customerId=CUSTOMER_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Update a Rule
curl -X PUT https://coreapi.io/api/wallet/auto-top-up/RULE_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"thresholdAmount": 20.00,
"topUpAmount": 200.00,
"enabled": false
}'
All fields are optional — only include the fields you want to change.
| Field | Type | Description |
|---|
thresholdAmount | number | New threshold (must be > 0) |
topUpAmount | number | New top-up amount (must be > 0) |
paymentMethodId | string | New payment method UUID |
enabled | boolean | Enable or disable the rule |
Delete a Rule
curl -X DELETE https://coreapi.io/api/wallet/auto-top-up/RULE_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Returns 204 No Content on success.
How Auto Top-Up Works
- A balance-reducing transaction occurs (e.g., wallet balance applied to an invoice)
- Fynn checks if an enabled auto top-up rule exists for the customer and currency
- If the ending balance is below the threshold, a top-up is initiated automatically
- The top-up follows the same flow as a manual top-up (PaymentIntent → payment → credit)
Safety mechanisms:
- Top-up transactions themselves do not trigger auto top-up (prevents loops)
- The
consecutiveFailures counter tracks sequential failures — monitor this to detect broken payment methods
- The feature must be enabled via the
WalletTopUp feature flag
Customer-Authenticated Requests
Customers authenticated via the customer portal can manage their own wallet:
- Top-up:
customerId is inferred from the authenticated session (do not include it)
- Auto top-up rules: Customers can only view/manage their own rules
- Attempting to access another customer’s data returns
403 Forbidden
# Customer-authenticated top-up (no customerId needed)
curl -X POST https://coreapi.io/api/wallet/top-up \
-H "Authorization: Bearer CUSTOMER_TOKEN" \
-d '{
"amount": 50.00,
"currencyCode": "EUR"
}'
Error Handling
| Status Code | Scenario |
|---|
400 Bad Request | Missing required field, duplicate rule for same currency |
403 Forbidden | Feature not enabled, or customer accessing another customer’s data |
404 Not Found | Rule or top-up not found |
422 Unprocessable Entity | Invalid amounts (zero, negative), invalid currency code |
Integration Example
const FYNN_API = 'https://coreapi.io';
const API_KEY = process.env.FYNN_API_KEY;
async function ensureWalletFunded(customerId, minBalance = 10, topUpAmount = 100) {
// Check if auto top-up rule exists
const rules = await fetch(
`${FYNN_API}/api/wallet/auto-top-up?customerId=${customerId}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
).then(r => r.json());
if (rules.items.length === 0) {
// Create auto top-up rule
await fetch(`${FYNN_API}/api/wallet/auto-top-up`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`,
},
body: JSON.stringify({
customerId,
currencyCode: 'EUR',
thresholdAmount: minBalance,
topUpAmount: topUpAmount,
}),
});
}
}