Overview
The Valescrow API provides programmatic access to conditional fund allocation and escrow, cross-border stablecoin payments, refunds, payroll disbursement, and withdrawal to local bank accounts across 15 Mento stablecoin currencies. Specify your currency per request (NGNm, KESm, GHSm, USDm, GBPm, EURm, and more). All responses are JSON.
Base URL & Environments
Production: https://api.usetappay.app/v1
Sandbox: https://sandbox.usetappay.app/v1Two key prefixes determine environment:
tap_live_sk_xxx— production (mainnet Celo, real money)tap_test_sk_xxx— sandbox (Celo Sepolia testnet, no real money)
Authentication
All requests require a Bearer token:
Authorization: Bearer tap_live_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAPI Keys
Generate API keys from the Valescrow dashboard (Settings → API Keys) or the TapPay mobile app (Settings → Developer → Generate API Key). Keys are shown once at creation — store them securely.
Errors
All errors return a consistent shape:
{
"error": "Human-readable description",
"code": "MACHINE_READABLE_CODE"
}Allocation & Escrow
Lifecycle:
CREATE ──> FUND ──> [ALL CONDITIONS MET] ──> RELEASE ──> RECIPIENTS PAID
| | ^
draft funded conditions checked on:
- each approval submitted
- each milestone triggered
- time locks expiring
- on funding (for 'immediate' type)
Status values:
draft created, not yet funded
funded full amount escrowed, conditions pending
releasing disbursement in progress (multicall batches)
released all recipients paid
partial some transfers failed - review required
cancelled cancelled, refund issued if funded
expired funding deadline passedConditions Reference
Conditions are evaluated every time an approval, milestone, or time event fires. When ALL root-level conditions are met, disbursement begins automatically.
Tiered Milestones
Milestone conditions can optionally define quality/quantity tiers, each mapped to a release percentage. When an inspector confirms a milestone, they select a tier — and only that percentage of linked recipient amounts is released. Unreleased funds are held for a configurable dispute window (default 7 days), then automatically returned to the allocation creator.
{
"type": "milestone",
"label": "Goods inspection",
"milestone_key": "inspection_PO-441",
"inspector_email": "inspector@example.com",
"milestone_tiers": [
{ "label": "Below minimum", "release_percent": 0 },
{ "label": "Partially delivered", "release_percent": 50 },
{ "label": "Substantially delivered", "release_percent": 75 },
{ "label": "Fully delivered", "release_percent": 100 }
]
}Tier constraints:
- Minimum 2 tiers when
milestone_tiersis provided - Must include at least one tier with
release_percent: 0(rejection) and one withrelease_percent > 0 - Tiers must be sorted ascending by
release_percent - Each tier:
label(non-empty string),release_percent(0–100) inspector_emailis optional — receives email notification with inspection link when allocated
POST/v1/allocations
Create a new conditional allocation. Recipients receive funds only when all conditions are met.
const alloc = await tappay.allocations.create({
title: 'Q1 2026 Education Budget',
reference: 'LSG-EDU-Q1-2026',
currency: 'NGNm',
total_amount: 50_000_000,
acknowledge_large_allocation: true,
recipients: [
{ wallet: '0xPrimarySchools...', amount: 20_000_000, label: 'Primary Schools' },
{ wallet: '0xSecondarySchools...', amount: 25_000_000, label: 'Secondary Schools' },
{ wallet: '0xAdmin...', amount: 5_000_000, label: 'Administration', condition_index: 1 },
],
conditions: [
{
type: 'manual_approval',
label: 'Board approval - 2 of 3 required',
required_approvals: 2,
approver_wallets: ['0xAuditor1...', '0xAuditor2...', '0xMinister...'],
},
{
type: 'time_lock',
label: 'Not before Q2 2026',
release_after: '2026-04-01T08:00:00Z',
},
],
});
console.log(alloc.allocation_id); // "alc_01JXYZ..."Field constraints:
title: 1–200 characters, requiredtotal_amount: must be > 0recipients: 1–1,000 items. Sum of amounts must equal total_amountconditions: 1–20 itemswallet: valid Celo address (0x + 40 hex chars)milestone_key: globally unique across all allocationsmilestone_tiers: optional array of tiers (see Tiered Milestones)inspector_email: optional, receives email notification with inspection linkacknowledge_large_allocation: required when total_amount > 500,000,000
Trade escrow with tiered inspection:
const escrow = await tappay.allocations.create({
title: 'PO-441 - 500 bags of maize',
reference: 'PO-441',
category: 'trade_escrow',
currency: 'KESm',
total_amount: 250_000,
recipients: [
{ wallet: '0xVendorWallet...', amount: 250_000, label: 'Vendor Ochieng' },
],
conditions: [
{
type: 'milestone',
label: 'Delivery confirmed by inspector',
milestone_key: 'delivery_PO-441',
inspector_email: 'inspector@logistics.co',
milestone_tiers: [
{ label: 'Below minimum', release_percent: 0 },
{ label: 'Partial delivery', release_percent: 70 },
{ label: 'Full delivery', release_percent: 100 },
],
},
],
});
// Inspector receives email notification with inspection link
// Fund via escrow.payment_url, then inspector confirms on deliveryPOST/v1/allocations/fund
Called after the funder sends stablecoin to the Valescrow service wallet. Verifies the on-chain transaction, deducts the platform fee, and locks the remaining amount for recipients.
const result = await tappay.allocations.fund({
allocation_id: 'alc_01JXYZ...',
tx_hash: '0xfunding_transaction_hash...',
});
console.log(result.status); // "funded"
console.log(result.platform_fee); // 125000
console.log(result.escrowed_for_recipients); // 49875000If all conditions are type immediate, status will be releasing immediately and funds begin disbursing.
POST/v1/allocations/approve
Submit an approval for a manual_approval condition. Returns 403 if approver_wallet is not in the condition's approver_wallets list.
const result = await tappay.allocations.approve({
allocation_id: 'alc_01JXYZ...',
condition_id: 'cond_uuid_1',
approver_wallet: '0xAuditor1...',
note: 'Reviewed and approved',
});
console.log(result.approval_count); // 1
console.log(result.condition_met); // false
console.log(result.all_conditions_met); // falseWhen condition_met becomes true, all conditions are re-evaluated. If all_conditions_met is true, disbursement begins immediately.
POST/v1/allocations/milestone
Trigger a milestone condition from your external system. Authenticated by HMAC-SHA256 — not by API key. Supports three actions: confirm (default), reject, and pending.
HMAC-SHA256(milestone_key + ":" + timestamp.toString(), milestone_secret)Timestamp must be within 300 seconds of server time (replay protection).
Request body fields:
milestone_key(required): the milestone's unique keytimestamp(required): Unix timestamp (seconds)signature(required): HMAC-SHA256 hex signatureaction(optional):"confirm"(default),"reject", or"pending"tier_index(optional): index intomilestone_tiersarray — required when action is"confirm"and tiers existnote(optional): inspector note — required when action is"reject"
import { AllocationResource } from '@tappay/sdk';
const { signature, timestamp } = AllocationResource.signMilestone(
'delivery_PO-441',
milestoneSecret
);
// Simple confirmation (no tiers)
await tappay.allocations.triggerMilestone({
milestone_key: 'delivery_PO-441',
timestamp,
signature,
note: 'Confirmed delivery at warehouse',
});
// Tiered confirmation — select tier by index
await tappay.allocations.triggerMilestone({
milestone_key: 'delivery_PO-441',
timestamp,
signature,
action: 'confirm',
tier_index: 2, // "Fully delivered" (100%)
note: 'All items verified',
});Reject and Pending actions:
// Reject — requires a reason in note field
await tappay.allocations.triggerMilestone({
milestone_key: 'delivery_PO-441',
timestamp,
signature,
action: 'reject',
note: 'Goods did not match specification',
});POST/v1/allocations/metric
Push metric data to a milestone with a metric inspector. Instead of a human confirming a milestone, any external system — IoT sensors, ERPs, logistics platforms, monitoring tools, CI/CD pipelines — can push data points via this endpoint. When the metric value crosses a configured threshold, the milestone auto-confirms and funds release without human intervention.
Uses the same HMAC-SHA256 authentication as POST /allocations/milestone.
Metric types:
counter— each push increments the running total (e.g. deliveries completed, units manufactured, vaccinations administered)keyword_count— increments a count each time a tracked keyword is detectedpercentage— latest reading replaces previous value (e.g. inspection score, completion percentage, quality rating)boolean— pass 1 for true, 0 for false (e.g. compliance check passed, temperature within range)
Comparison operators:
gte(default) — auto-confirm when value ≥ threshold (e.g. "release when 20 deliveries completed")lte— auto-confirm when value ≤ threshold (e.g. "release when defect rate drops to 2% or below")eq— auto-confirm when value equals threshold exactly
Request body fields:
milestone_key(required): the milestone's unique keytimestamp(required): Unix timestamp (seconds)signature(required): HMAC-SHA256 hex signature (same as milestone trigger)value(required): the metric value to pushmetadata(optional): JSON object with context (e.g. sensor ID, batch number, GPS coordinates)
import { AllocationResource } from '@tappay/sdk';
const { signature, timestamp } = AllocationResource.signMilestone(
'warehouse-deliveries',
milestoneSecret
);
// Push a counter increment — e.g. 4.5 tonnes delivered
await tappay.allocations.pushMetric({
milestone_key: 'warehouse-deliveries',
timestamp,
signature,
value: 4.5,
metadata: { truck_id: 'LG-4821', location: 'Apapa Warehouse' },
});Setting up a metric inspector
Add a metric_inspector field when creating a milestone condition. The metric inspector defines what data to track, how to accumulate it, and at what threshold to auto-confirm.
// Counter — release when 20 tonnes delivered
{
"type": "milestone",
"label": "Commodity delivery to warehouse",
"metric_inspector": {
"metric_key": "tonnes-delivered",
"metric_type": "counter",
"threshold": 20,
"comparison": "gte"
}
}
// Percentage — release when inspection score reaches 85%
{
"type": "milestone",
"label": "Building inspection score",
"metric_inspector": {
"metric_key": "inspection-score",
"metric_type": "percentage",
"threshold": 85,
"comparison": "gte"
}
}
// Boolean — release when compliance check passes
{
"type": "milestone",
"label": "Regulatory compliance verified",
"metric_inspector": {
"metric_key": "compliance-check",
"metric_type": "boolean",
"threshold": 1,
"comparison": "eq"
}
}Tiered release with metric thresholds
Combine milestone_tiers with tier_thresholds to release funds progressively as metrics accumulate. Each tier threshold maps a metric value to a tier index — when the metric crosses a threshold, the corresponding tier activates and its release percentage applies.
{
"type": "milestone",
"label": "Vaccination campaign progress",
"milestone_tiers": [
{ "label": "Phase 1 — 1,000 vaccinations", "release_percent": 30 },
{ "label": "Phase 2 — 5,000 vaccinations", "release_percent": 70 },
{ "label": "Phase 3 — 10,000 vaccinations", "release_percent": 100 }
],
"metric_inspector": {
"metric_key": "vaccination-count",
"metric_type": "counter",
"threshold": 10000,
"comparison": "gte",
"tier_thresholds": [
{ "min_value": 1000, "tier_index": 0 },
{ "min_value": 5000, "tier_index": 1 },
{ "min_value": 10000, "tier_index": 2 }
]
}
}When the counter reaches 1,000 → tier 0 activates (30% released). At 5,000 → tier 1 (70%). At 10,000 → tier 2 (100%). Each tier upgrade triggers a webhook and audit log entry.
Connecting external systems
Any system that can make an HTTP POST request can push metrics to Valescrow. Here are common integration patterns:
- IoT & sensors — warehouse scales, temperature monitors, GPS trackers push readings on a schedule or event trigger
- ERP & supply chain — SAP, Odoo, or custom systems push delivery confirmations, invoice counts, or inventory levels via webhook
- Project management — Jira, Asana, or custom dashboards push task completion counts or sprint progress
- CI/CD pipelines — GitHub Actions or Jenkins push build pass counts or deployment success flags
- Healthcare systems — clinic software pushes patient counts, vaccination records, or treatment completions
- Financial systems — accounting software pushes revenue milestones, collection totals, or audit completion flags
The integration is a single HTTP call. Use signMilestone() from the SDK for HMAC signing, or compute HMAC-SHA256(milestone_key:timestamp, milestone_secret) in any language.
inspector_email (human) and a metric_inspector (programmatic). Either can trigger confirmation — whichever happens first. This lets you set up automatic confirmation with a human fallback, or vice versa.GET /v1/allocations/milestone/[token] — No Auth Required
For field officers who need to confirm a milestone without an account. Each milestone condition has a unique URL:
https://valescrow.com/milestone/[token]GET returns allocation title, condition label, current status, and milestone tiers (if defined). POST with action, tier_index, and note triggers the milestone. No API key required — the token is the authentication.
// POST body for field officer confirmation
{ "confirm": true, "action": "confirm", "tier_index": 2, "note": "All items verified" }
// POST body for rejection
{ "confirm": true, "action": "reject", "note": "Items damaged in transit" }
// POST body for pending/in-progress
{ "confirm": true, "action": "pending", "note": "Inspection underway" }The designated inspector receives an email notification with the token link when the allocation is created (if inspector_email is provided).
POST/v1/allocations/cancel
Cancels an allocation and refunds escrowed funds on-chain. Cannot cancel if status is releasing or released.
escrowed_for_recipients, not the original gross amount.const result = await tappay.allocations.cancel({
allocation_id: 'alc_01JXYZ...',
reason: 'Project scope changed',
});
console.log(result.refund_tx_hash); // "0xrefund_hash..."GET/v1/allocations/:id
Full allocation detail including recipients, conditions, approvals, dispute status, and complete audit trail.
{
"id": "alc_01JXYZ...",
"title": "Q1 2026 Education Budget",
"description": "...",
"reference": "LSG-EDU-Q1-2026",
"category": "government_budget",
"currency": "NGNm",
"total_amount": 50000000,
"platform_fee": 125000,
"escrowed_amount": 49875000,
"status": "funded",
"conditions_met": false,
"funded_at": "2026-03-17T22:00:00.000Z",
"funding_tx_hash": "0xfunding...",
"released_at": null,
"cancelled_at": null,
"created_at": "2026-03-17T21:00:00.000Z",
"payment_url": "https://usetappay.app/fund/alc_01JXYZ...",
"dispute_window_hours": 168,
"tier_dispute_deadline": null,
"unreleased_amount": 0,
"unreleased_refunded": false,
"refund_tx_hash": null,
"recipients": [{
"id": "recip_uuid",
"wallet": "0xPrimarySchools...",
"label": "Primary Schools Dept",
"category": "education",
"amount": 19950000,
"released_amount": null,
"status": "pending",
"tx_hash": null,
"condition_id": null,
"completed_at": null
}],
"conditions": [{
"id": "cond_uuid_1",
"type": "manual_approval",
"label": "Board of Trustees (2 of 3)",
"is_met": false,
"met_at": null,
"required_approvals": 2,
"approval_count": 1,
"approver_wallets": ["0xAuditor1", "0xAuditor2", "0xMinister"],
"release_after": null,
"milestone_key": null,
"milestone_tiers": null,
"inspector_email": null,
"selected_tier_index": null,
"inspection_status": "pending",
"inspection_note": null,
"rejected_at": null,
"rejection_reason": null,
"sort_order": 0
}],
"approvals": [{
"condition_id": "cond_uuid_1",
"approver_wallet": "0xAuditor1",
"note": "Reviewed and approved",
"created_at": "2026-03-17T22:30:00.000Z"
}],
"audit_log": [
{
"event": "created",
"actor_type": "api",
"detail": { "recipient_count": 2, "condition_count": 3, "total_amount": 50000000 },
"created_at": "2026-03-17T21:00:00.000Z"
},
{
"event": "platform_fee_collected",
"actor_type": "system",
"detail": {
"fee": 250000, "fee_rate": 0.005, "fee_type": "standard",
"gross_amount": 50000000, "escrowed_for_recipients": 49750000,
"fee_tx_hash": "0xfee..."
},
"created_at": "2026-03-17T22:00:00.000Z"
},
{
"event": "funded",
"actor_type": "system",
"detail": { "tx_hash": "0xfunding...", "amount": 50000000 },
"created_at": "2026-03-17T22:00:00.000Z"
},
{
"event": "approved",
"actor_wallet": "0xAuditor1",
"actor_type": "approver",
"detail": {
"note": "Reviewed and approved",
"count": "1/2",
"condition_label": "Board of Trustees (2 of 3)"
},
"created_at": "2026-03-17T22:30:00.000Z"
}
]
}New fields explained:
dispute_window_hours: hours before unreleased funds are refunded (default 168 = 7 days)tier_dispute_deadline: ISO timestamp when dispute window expires (null if no tiered release)unreleased_amount: amount held pending dispute window expiryunreleased_refunded: whether unreleased funds have been returned to creatorrefund_tx_hash: on-chain transaction hash of the unreleased funds refundreleased_amount(on recipients): actual release amount after tier selection — null means full amountmilestone_tiers(on conditions): array of tier definitions, or nullinspection_status:pending,in_progress,confirmed, orrejectedselected_tier_index: which tier was selected by inspector (index into milestone_tiers)inspection_note: note from inspectorrejection_reason: reason provided when inspector rejects
GET/v1/allocations
List allocations. Query params: status, limit (default 20, max 100), offset.
{
"allocations": [{
"id": "alc_01JXYZ...",
"title": "Q1 2026 Education Budget",
"reference": "LSG-EDU-Q1-2026",
"currency": "NGNm",
"total_amount": 50000000,
"status": "funded",
"conditions_met": false,
"recipient_count": 2,
"funded_at": "2026-03-17T22:00:00.000Z",
"released_at": null,
"created_at": "2026-03-17T21:00:00.000Z"
}],
"total": 7,
"has_more": false
}Allocation Discovery
The Allocation Discovery Platform lets investors browse publicly listed allocations without authentication. Creators opt in via the is_discoverable flag at creation time or the portal toggle. All responses are public-safe — zero wallet addresses, secrets, or inspector emails are ever returned.
GET/v1/allocations/public
List discoverable allocations. No API key required. Rate limited to 30 requests/min per IP. Responses are cached for 30 seconds.
Query parameters
// No API key needed for public discovery
const tappay = new TapPay('tap_live_sk_xxx');
const result = await tappay.allocations.listPublic({
category: 'real_estate_fractional',
currency: 'NGNm',
limit: 10,
});
for (const alloc of result.allocations) {
console.log(alloc.title, alloc.funding_progress.percent + '% funded');
}Making allocations discoverable
Pass is_discoverable: true when creating an allocation via the API. You can also set a public-facing title and description that differs from the internal allocation details.
const alloc = await tappay.allocations.create({
title: 'Internal: Lekki Phase 2 Round A',
total_amount: 500_000_000,
currency: 'NGNm',
is_discoverable: true,
discoverable_title: 'Lekki Phase 2 — 40-Unit Apartment Complex',
discoverable_description: 'Fractional ownership in a 40-unit luxury apartment development in Lekki Phase 2, Lagos.',
template_id: 're_fractional',
recipients: [/* ... */],
conditions: [/* ... */],
});RWA template reference
Valescrow provides 16 pre-built RWA templates across five sectors. Each template maps to existing condition types — no new backend logic. Pass the template_id when creating allocations for analytics tracking.
Payments
POST/v1/payment-requests
Create a payment request (invoice) that can be paid via the TapPay consumer app or web page.
const request = await tappay.paymentRequests.create({
amount: 5000,
reference: 'INV-001',
description: 'Consultation fee',
splits: [
{ wallet: '0xDoctor...', amount: 3500, label: 'Doctor fee' },
{ wallet: '0xPlatform...', amount: 1500, label: 'Platform fee' },
],
});
console.log(request.payment_url);splits: optional, max 5 recipients. Sum must equal amount. Splits enable automatic revenue distribution on payment — each recipient receives their share on-chain in a single transaction.
currency: any Mento stablecoin (NGNm, KESm, GHSm, USDm, GBPm, EURm, ZARm, XOFm, etc.). Defaults to NGNm if omitted.
GET/v1/payment-requests
GET/v1/payment-requests/:id
Returns full PaymentRequest including refunded_amount.
GET/v1/verify/:reference
Verify payment by your reference string. Returns full PaymentRequest including refund history and split statuses.
const result = await tappay.paymentRequests.verify('INV-001');
if (result.data.status === 'completed') {
console.log('Paid!', result.data.tx_hash);
}Transactions
GET/v1/transactions
Query params: type (sent | received), from, to, amount_min, amount_max, limit, offset.
{
"transactions": [{
"id": "txn_01J...",
"type": "received",
"amount": "5000",
"currency": "NGNm",
"counterparty": "0xPayer...",
"tx_hash": "0xabc123...",
"status": "confirmed",
"created_at": "2026-03-17T22:00:00.000Z"
}],
"total": 124,
"has_more": true
}Refunds
Both full and partial refunds supported. Transfers the original stablecoin on-chain back to the payer's wallet.
POST/v1/refunds
Omit amount for a full refund. Partial refunds can be issued multiple times until the full original amount is refunded.
const refund = await tappay.refunds.create({
payment_request_id: 'pr_01J...',
amount: 2500,
reason: 'Doctor cancelled appointment',
});
console.log(refund.status); // "completed"Fires: refund.completed or refund.failed webhook.
GET/v1/refunds
List all refunds. Supports payment_request_id, limit, offset query params.
GET/v1/refunds/:id
Get a single refund by ID.
Balance & Payouts
GET/v1/balance
{
"balances": [
{ "currency": "NGNm", "balance": "284500.00", "fiat_symbol": "₦" },
{ "currency": "KESm", "balance": "0.00", "fiat_symbol": "KSh" }
],
"wallet_address": "0xYourWallet...",
"environment": "live"
}POST/v1/payouts
Withdraw stablecoin balance to a local bank account. TapPay's smart router automatically selects the best payout partner based on currency, fees, and availability.
Nigeria (NGNm → NGN):
• Platform fee: 0.75% (min ₦100)
• NIBSS transfer fee: ₦52.50 (regulatory pass-through)
• Stamp duty: ₦50.00 (regulatory pass-through)
Other corridors have different fee structures. Use
GET /v1/rail-fees?currency=KESm to retrieve fees for a specific currency at runtime.const payout = await tappay.payouts.create({
amount: 50000,
currency: 'NGNm', // or KESm, GHSm, USDm, etc.
bank_code: '044',
account_number: '0123456789',
reference: 'PAYOUT-001',
});Webhooks
TapPay sends signed HTTP POST requests to your endpoint when events occur. Deliveries are retried on failure.
const webhook = await tappay.webhooks.create({
url: 'https://your-app.com/webhooks/tappay',
events: ['payment.received', 'allocation.released', 'refund.completed'],
});
// Store webhook.secret for signature verificationPayload envelope:
{
"event": "allocation.released",
"created": 1742248800000,
"data": { ... }
}All Webhook Events
Payment events:
Allocation events:
Verifying Signatures
import { TapPay } from '@tappay/sdk';
app.post('/webhooks/tappay', (req, res) => {
const isValid = TapPay.webhooks.verify(
req.rawBody,
req.headers['tappay-signature'],
webhookSecret
);
if (!isValid) return res.status(401).send('Invalid signature');
const { event, data } = JSON.parse(req.rawBody);
// handle event...
res.status(200).send('ok');
});Retry Logic
Delivery attempted up to 4 times on failure:
- Attempt 1: immediate
- Attempt 2: 1 minute later
- Attempt 3: 5 minutes later
- Attempt 4: 30 minutes later
Your endpoint must return 2xx within 10 seconds. After 4 failures the webhook is disabled. Re-enable via dashboard.
Limits & Quotas
Allocation Tiers
Max recipients per allocation: 1,000. Max conditions per allocation: 20. Max splits per payment request: 5.
Throughput
Disbursements use on-chain multicall batching:
- 100 recipients per multicall transaction
- 1,000 recipients processed in ~10 transactions (~2 minutes)
- 10,000 recipients processed in ~100 transactions (~20 minutes)
API Rate Limits
Rate limit headers on every response:
X-RateLimit-Remaining: 94
Retry-After: 12 // only on 429 responsesSDK Reference
Installation
npm install @tappay/sdkimport { TapPay } from '@tappay/sdk';
const tappay = new TapPay('tap_live_sk_xxx');Resources
tappay.paymentRequests // .create() .get() .list() .verify()
tappay.transactions // .list()
tappay.refunds // .create() .get() .list()
tappay.balance // .get()
tappay.payouts // .create()
tappay.webhooks // .create() .list() .delete()
tappay.allocations // .create() .fund() .get() .list()
// .approve() .triggerMilestone() .cancel()
// Static - no instance needed:
TapPay.webhooks.verify(payload, signature, secret)
AllocationResource.signMilestone(milestoneKey, milestoneSecret)TypeScript types:
import type {
PaymentRequest, Allocation, AllocationStatus,
ConditionType, CreateAllocationParams,
FundAllocationResponse,
} from '@tappay/sdk';Error Handling
import { TapPay, TapPayError } from '@tappay/sdk';
try {
const alloc = await tappay.allocations.create({ ... });
} catch (err) {
if (err instanceof TapPayError) {
console.error(err.message); // human-readable
console.error(err.statusCode); // HTTP status
console.error(err.body); // full error response including code
}
}