Escrow API
The Escrow API enables secure payment handling with customizable terms and conditions that must be fulfilled before funds are released. This comprehensive guide covers authentication flows, escrow operations, term fulfillment, release, and reverse operations with practical examples.
Table of Contents
Authentication Overview
The Escrow API supports multiple authentication methods depending on the payment method and user type:
Authentication Matrix
Payment Method |
Registered Users |
Unregistered Users |
Merchant Actions |
|---|---|---|---|
piaxis |
OAuth2 Bearer Token |
N/A (must be registered) |
API Key |
piaxis_external |
OAuth2 Bearer Token |
OTP Verification |
API Key + Bearer Token |
mtn |
OAuth2 Bearer Token |
OTP Verification |
API Key |
airtel |
OAuth2 Bearer Token |
OTP Verification |
API Key |
card |
OAuth2 Bearer Token |
OTP Verification |
API Key |
Required Headers
For all requests:
Content-Type: application/json
X-Piaxis-Client-ID: your_client_id
API Key Authentication (Merchant):
api-key: YOUR_MERCHANT_API_KEY
OAuth2 Authentication (User):
Authorization: Bearer YOUR_ACCESS_TOKEN
Combined Authentication (piaxis_external):
api-key: YOUR_MERCHANT_API_KEY
Authorization: Bearer YOUR_ACCESS_TOKEN
OTP Verification for Unregistered Users
For unregistered users on external payment methods (mtn, airtel, card), OTP verification is required:
-
Request OTP:
POST /api/request-otp HTTP/1.1
Host: api.gopiaxis.com
Content-Type: application/json
api-key: YOUR_API_KEY
{
"phone_number": "+256700000000",
"email": "[email protected]"
}
-
Use OTP in escrow creation:
{
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Quick Start Guide
This section provides a step-by-step walkthrough for common escrow scenarios.
Scenario 1: Simple MTN Escrow with Delivery Confirmation
Step 1: Create the escrow
POST /api/escrows/ HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
X-Piaxis-Client-ID: piaxis_bd97ffb5144c49e4
Content-Type: application/json
{
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount": "50000.00",
"currency_code": "UGX",
"payment_method": "mtn",
"description": "Payment for electronics order #12345",
"terms": [
{
"type": "delivery_confirmation",
"data": {
"description": "Confirm receipt of electronics order",
"deadline": "2024-12-14T23:59:59Z"
}
}
],
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Response:
{
"escrow_id": "f530533e-3761-4cde-9c9d-88c5be6493bb",
"status": "pending",
"amount": "50000.00",
"currency": "UGX",
"payment_method": "mtn",
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"terms": [
{
"term_id": "4215567e-6928-4a9d-85d8-c3b1708bdcec",
"type": "delivery_confirmation",
"status": "pending",
"deadline": "2024-12-14T23:59:59Z"
}
],
"created_at": "2024-12-07T10:30:00Z"
}
Step 2: Buyer confirms delivery (fulfills term)
POST /api/escrows/f530533e-3761-4cde-9c9d-88c5be6493bb/terms/4215567e-6928-4a9d-85d8-c3b1708bdcec/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "delivery_confirmation",
"data": {
"confirmation_method": "confirmation",
"notes": "Package received in good condition"
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Step 3: Release funds automatically or manually
Once all terms are fulfilled, funds can be released automatically or manually triggered:
POST /api/escrows/f530533e-3761-4cde-9c9d-88c5be6493bb/release HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Creating Escrows
The escrow creation endpoint supports various payment methods and term combinations.
- POST /api/escrows/
-
Create a new escrow payment with specified terms and conditions.
- Request Headers:
-
-
api-key – Merchant API key (required)
-
X-Piaxis-Client-ID – Your client ID (required)
-
Authorization – Bearer token (required for piaxis_external, optional for others)
-
Content-Type – application/json
-
- Status Codes:
-
-
200 OK – Escrow created successfully
-
400 Bad Request – Invalid request parameters
-
401 Unauthorized – Authentication failed
-
403 Forbidden – Insufficient permissions
-
422 Unprocessable Entity – Validation errors
-
Payment Method Examples
MTN Money Escrow:
POST /api/escrows/ HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
X-Piaxis-Client-ID: piaxis_bd97ffb5144c49e4
Content-Type: application/json
{
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount": "25000.00",
"currency_code": "UGX",
"payment_method": "mtn",
"description": "Service payment with location verification",
"terms": [
{
"type": "location_verification",
"data": {
"latitude": 0.347596,
"longitude": 32.582520,
"radius": 100,
"description": "Verify location at delivery point"
}
}
],
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456",
"device_info": {
"device_id": "unique_device_id",
"platform": "android",
"os_version": "11.0"
}
}
}
Airtel Money Escrow:
POST /api/escrows/ HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
X-Piaxis-Client-ID: piaxis_bd97ffb5144c49e4
Content-Type: application/json
{
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount": "75000.00",
"currency_code": "UGX",
"payment_method": "airtel",
"description": "Product purchase with meeting delivery",
"products": [
{
"product_id": "7c8b7cbe-4d52-4097-9fb2-858be26f5338",
"quantity": 1,
"selected_location": {
"latitude": 0.3476,
"longitude": 32.5825
}
}
],
"terms": [
{
"type": "meeting_delivery",
"data": {
"max_distance_km": 0.1,
"buyer_coordinates": {
"latitude": 0.3476,
"longitude": 32.5825
},
"description": "Meet at central market for product delivery"
}
}
],
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Piaxis External Payment:
POST /api/escrows/ HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Authorization: Bearer YOUR_ACCESS_TOKEN
X-Piaxis-Client-ID: piaxis_bd97ffb5144c49e4
Content-Type: application/json
{
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount": "100000.00",
"currency_code": "UGX",
"payment_method": "piaxis_external",
"description": "High-value transaction with multiple terms",
"terms": [
{
"type": "photo_upload",
"data": {
"description": "Upload proof of service completion",
"required_count": 2,
"accepted_formats": ["jpeg", "png"]
}
},
{
"type": "delivery_confirmation",
"data": {
"description": "Confirm service completion",
"deadline": "2024-12-20T18:00:00Z"
}
}
]
}
Card Payment Escrow:
POST /api/escrows/ HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
X-Piaxis-Client-ID: piaxis_bd97ffb5144c49e4
Content-Type: application/json
{
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount": "50000.00",
"currency_code": "UGX",
"payment_method": "card",
"description": "Online purchase with return period",
"terms": [
{
"type": "return_period",
"data": {
"return_period_days": 7,
"start_date": "2024-12-07T00:00:00Z",
"description": "7-day return window for online purchase"
}
}
],
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "654321"
}
}
Term Types and Data Structures
Available Term Types:
-
delivery_confirmation- Simple confirmation from buyer/seller -
location_verification- GPS location verification -
meeting_delivery- In-person meeting with location verification -
photo_upload- Photo evidence upload -
return_period- Time-based return window -
custom- Custom merchant-defined terms
Request Body Structure:
{
"receiver_id": "string (UUID)",
"amount": "decimal",
"currency_code": "string (ISO 4217)",
"payment_method": "piaxis_external|mtn|airtel|card",
"description": "string (optional)",
"products": [
{
"product_id": "string (UUID)",
"quantity": "integer",
"selected_location": {
"latitude": "float",
"longitude": "float"
}
}
],
"terms": [
{
"type": "string",
"data": "object (varies by term type)"
}
],
"user_info": {
"email": "string",
"phone_number": "string",
"otp": "string (for unregistered users)",
"device_info": {
"device_id": "string",
"platform": "string",
"os_version": "string"
}
}
}
Term Fulfillment
The universal fulfillment endpoint handles all term types with role-based authentication.
- POST /api/escrows/{escrow_id}/terms/{term_id}/fulfill
-
Fulfill a specific term of an escrow. The system automatically determines the user’s role (buyer/seller) and validates permissions.
- Request Headers:
-
-
api-key – Merchant API key (required)
-
Authorization – Bearer token (optional, for registered users)
-
Content-Type – application/json
-
- Status Codes:
-
-
200 OK – Term fulfilled successfully
-
400 Bad Request – Invalid fulfillment data
-
401 Unauthorized – Authentication failed
-
403 Forbidden – User not authorized for this term
-
404 Not Found – Escrow or term not found
-
409 Conflict – Term already fulfilled or conditions not met
-
Delivery Confirmation Examples
Buyer Confirmation:
POST /api/escrows/f530533e-3761-4cde-9c9d-88c5be6493bb/terms/4215567e-6928-4a9d-85d8-c3b1708bdcec/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "delivery_confirmation",
"data": {
"confirmation_method": "confirmation",
"notes": "Package received in excellent condition. Very satisfied!",
"rating": 5
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Seller Confirmation:
POST /api/escrows/f530533e-3761-4cde-9c9d-88c5be6493bb/terms/4215567e-6928-4a9d-85d8-c3b1708bdcec/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "delivery_confirmation",
"data": {
"confirmation_method": "confirmation",
"notes": "Product delivered successfully to customer",
"delivery_timestamp": "2024-12-07T14:30:00Z"
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256701000000",
"otp": "654321"
}
}
Merchant Acting on Behalf of User:
POST /api/escrows/f530533e-3761-4cde-9c9d-88c5be6493bb/terms/4215567e-6928-4a9d-85d8-c3b1708bdcec/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "delivery_confirmation",
"data": {
"confirmation_method": "confirmation",
"notes": "Confirmed delivery on behalf of customer via customer service",
"merchant_action": true,
"confirmation_source": "customer_service_call"
}
}
Location Verification Examples
User Location Verification:
POST /api/escrows/abc123e4-5678-4def-9012-345678901234/terms/def456a7-8901-4bcd-2345-678901234567/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "location_verification",
"data": {
"user_latitude": 0.347596,
"user_longitude": 32.582520,
"accuracy": 5.2,
"timestamp": "2024-12-07T10:15:30Z",
"device_info": {
"device_id": "user_device_456",
"platform": "ios",
"os_version": "15.0"
}
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "789123"
}
}
Meeting Delivery Examples
Buyer Meeting Confirmation:
POST /api/escrows/meeting123-4567-4abc-8901-234567890123/terms/meeting456-7890-4def-1234-567890123456/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "meeting_delivery",
"data": {
"buyer_latitude": 0.3476,
"buyer_longitude": 32.5825,
"meeting_timestamp": "2024-12-07T16:00:00Z",
"device_info": {
"device_id": "buyer_device_789",
"platform": "android",
"os_version": "12.0"
}
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "456789"
}
}
Seller Meeting Confirmation:
POST /api/escrows/meeting123-4567-4abc-8901-234567890123/terms/meeting456-7890-4def-1234-567890123456/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "meeting_delivery",
"data": {
"seller_latitude": 0.3476,
"seller_longitude": 32.5825,
"meeting_timestamp": "2024-12-07T16:05:00Z",
"device_info": {
"device_id": "seller_device_321",
"platform": "android",
"os_version": "11.0"
}
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256701000000",
"otp": "987654"
}
}
Photo Upload Examples
Single Photo Upload:
POST /api/escrows/photo123-4567-4abc-8901-234567890123/terms/photo456-7890-4def-1234-567890123456/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "photo_upload",
"data": {
"photos": [
{
"file_url": "https://storage.gopiaxis.com/uploads/proof-123.jpg",
"description": "Product delivered and installed",
"timestamp": "2024-12-07T14:30:00Z"
}
],
"notes": "Installation completed successfully"
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256702000000",
"otp": "321654"
}
}
Multiple Photo Upload:
POST /api/escrows/photo123-4567-4abc-8901-234567890123/terms/photo456-7890-4def-1234-567890123456/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "photo_upload",
"data": {
"photos": [
{
"file_url": "https://storage.gopiaxis.com/uploads/before-123.jpg",
"description": "Before installation",
"timestamp": "2024-12-07T09:00:00Z"
},
{
"file_url": "https://storage.gopiaxis.com/uploads/after-123.jpg",
"description": "After installation - completed work",
"timestamp": "2024-12-07T14:30:00Z"
}
],
"completion_notes": "Full installation with before/after documentation"
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256703000000",
"otp": "159753"
}
}
Custom Term Examples
Custom Verification Term:
POST /api/escrows/custom123-4567-4abc-8901-234567890123/terms/custom456-7890-4def-1234-567890123456/fulfill HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"term_type": "custom",
"data": {
"verification_code": "CUSTOM-VERIFY-789",
"completion_data": {
"task_completed": true,
"verification_timestamp": "2024-12-07T18:00:00Z",
"additional_info": "Custom task completed according to specifications"
}
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256704000000",
"otp": "753951"
}
}
Escrow Operations
Once escrows are created and terms are fulfilled, you can perform various operations to manage the escrow lifecycle.
Releasing Escrows
Release funds from an escrow to the recipient once terms are satisfied.
- POST /api/escrows/{escrow_id}/release
-
Release escrowed funds to the receiver.
- Request Headers:
-
-
api-key – Merchant API key (required)
-
Authorization – Bearer token (optional, for registered users)
-
Content-Type – application/json
-
- Status Codes:
-
-
200 OK – Escrow released successfully
-
400 Bad Request – Cannot release escrow (terms not met, already released, etc.)
-
401 Unauthorized – Authentication failed
-
403 Forbidden – User not authorized to release this escrow
-
404 Not Found – Escrow not found
-
Manual Release Example:
POST /api/escrows/43452aa2-28b4-4e8f-a1d2-d47014c9a33a/release HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"reason": "All delivery terms fulfilled successfully",
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Merchant-Authorized Release:
POST /api/escrows/43452aa2-28b4-4e8f-a1d2-d47014c9a33a/release HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"reason": "Customer service confirmed satisfaction via phone",
"merchant_authorization": true,
"authorization_reference": "CS-CALL-2024-001234"
}
Successful Release Response:
{
"escrow_id": "43452aa2-28b4-4e8f-a1d2-d47014c9a33a",
"status": "released",
"amount": "50000.00",
"currency": "UGX",
"released_at": "2024-12-07T15:30:00Z",
"release_transaction_id": "txn_987654321",
"receiver_info": {
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount_received": "49500.00",
"fees_deducted": "500.00"
}
}
Reversing Escrows
Reverse an escrow payment back to the sender when terms cannot be fulfilled or disputes arise.
- POST /api/escrows/{escrow_id}/reverse
-
Reverse an escrow payment back to the original sender.
- Request Headers:
-
-
api-key – Merchant API key (required)
-
Authorization – Bearer token (optional, for registered users)
-
Content-Type – application/json
-
- Status Codes:
-
-
200 OK – Escrow reversed successfully
-
400 Bad Request – Cannot reverse escrow (already released, invalid state, etc.)
-
401 Unauthorized – Authentication failed
-
403 Forbidden – User not authorized to reverse this escrow
-
404 Not Found – Escrow not found
-
Buyer-Initiated Reverse:
POST /api/escrows/43452aa2-28b4-4e8f-a1d2-d47014c9a33a/reverse HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"reason": "Product not as described - requesting full refund",
"reverse_type": "buyer_dissatisfaction",
"evidence": {
"description": "Product condition does not match listing",
"photos": [
"https://storage.gopiaxis.com/uploads/evidence-001.jpg"
]
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456"
}
}
Seller-Initiated Reverse:
POST /api/escrows/43452aa2-28b4-4e8f-a1d2-d47014c9a33a/reverse HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"reason": "Unable to fulfill order - item out of stock",
"reverse_type": "seller_cancellation",
"refund_processing_fee": false,
"user_info": {
"email": "[email protected]",
"phone_number": "+256701000000",
"otp": "654321"
}
}
Merchant-Mediated Reverse:
POST /api/escrows/43452aa2-28b4-4e8f-a1d2-d47014c9a33a/reverse HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Content-Type: application/json
{
"reason": "Dispute resolution - agreed refund after mediation",
"reverse_type": "dispute_resolution",
"merchant_mediation": true,
"resolution_details": {
"mediator_id": "mediator_123",
"resolution_date": "2024-12-07T10:00:00Z",
"agreed_terms": "Full refund minus processing fees"
}
}
Successful Reverse Response:
{
"escrow_id": "43452aa2-28b4-4e8f-a1d2-d47014c9a33a",
"status": "reversed",
"original_amount": "50000.00",
"refund_amount": "49000.00",
"fees_retained": "1000.00",
"currency": "UGX",
"reversed_at": "2024-12-07T16:45:00Z",
"reverse_transaction_id": "rev_123456789",
"sender_info": {
"refund_method": "mtn",
"refund_reference": "MTN-REF-789123"
}
}
Getting Escrow Status
Retrieve comprehensive status information about an escrow.
- GET /api/escrows/{escrow_id}/status
-
Get detailed status and progress of an escrow including term fulfillment status.
- Request Headers:
-
-
api-key – Merchant API key (required)
-
- Status Codes:
-
-
200 OK – Status retrieved successfully
-
401 Unauthorized – Authentication failed
-
404 Not Found – Escrow not found
-
Request Example:
GET /api/escrows/7680cfa9-b0cf-43a7-974b-108b89bd5ebe/status HTTP/1.1
Host: api.gopiaxis.com
api-key: YOUR_API_KEY
Detailed Response Example:
{
"escrow_id": "7680cfa9-b0cf-43a7-974b-108b89bd5ebe",
"status": "active",
"amount": "75000.00",
"currency": "UGX",
"payment_method": "airtel",
"created_at": "2024-12-05T09:30:00Z",
"expires_at": "2024-12-19T23:59:59Z",
"description": "Electronics purchase with delivery confirmation",
"participants": {
"sender": {
"type": "unregistered",
"email": "[email protected]",
"phone_number": "+256700000000",
"verified": true
},
"receiver": {
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"type": "registered",
"business_name": "Tech Solutions Ltd"
}
},
"terms": [
{
"term_id": "07a17756-a965-452a-9f0a-48ef55c38131",
"term_type": "delivery_confirmation",
"status": "fulfilled",
"description": "Confirm receipt of electronics",
"deadline": "2024-12-12T18:00:00Z",
"fulfilled_at": "2024-12-07T14:30:00Z",
"fulfilled_by": "buyer",
"fulfillment_data": {
"confirmation_method": "confirmation",
"notes": "Package received in excellent condition",
"rating": 5
}
},
{
"term_id": "08b28867-b076-463b-af1b-59fg66d49242",
"term_type": "location_verification",
"status": "pending",
"description": "Verify delivery location",
"deadline": "2024-12-12T18:00:00Z",
"required_location": {
"latitude": 0.347596,
"longitude": 32.582520,
"radius": 100
}
}
],
"progress": {
"total_terms": 2,
"fulfilled_terms": 1,
"pending_terms": 1,
"all_terms_met": false,
"completion_percentage": 50
},
"timeline": [
{
"timestamp": "2024-12-05T09:30:00Z",
"event": "escrow_created",
"description": "Escrow created with 2 terms"
},
{
"timestamp": "2024-12-07T14:30:00Z",
"event": "term_fulfilled",
"description": "Delivery confirmation completed by buyer",
"term_id": "07a17756-a965-452a-9f0a-48ef55c38131"
}
]
}
Error Handling
The Escrow API uses standard HTTP status codes and provides detailed error messages to help developers troubleshoot issues.
HTTP Status Codes
Error Response Format
All error responses follow a consistent format:
{
"detail": "Human-readable error message",
"error_code": "SPECIFIC_ERROR_CODE",
"errors": {
"field_name": ["Field-specific error message"],
"another_field": ["Another validation error"]
},
"request_id": "req_123456789"
}
Common Error Scenarios
Authentication Errors:
{
"detail": "Authentication failed",
"error_code": "INVALID_API_KEY",
"request_id": "req_auth_001"
}
Validation Errors:
{
"detail": "Validation failed",
"error_code": "VALIDATION_ERROR",
"errors": {
"amount": ["Amount must be greater than 0"],
"phone_number": ["Invalid phone number format"],
"terms": ["At least one term is required"]
},
"request_id": "req_val_002"
}
Business Logic Errors:
{
"detail": "Term already fulfilled",
"error_code": "TERM_ALREADY_FULFILLED",
"context": {
"term_id": "07a17756-a965-452a-9f0a-48ef55c38131",
"fulfilled_at": "2024-12-07T14:30:00Z",
"fulfilled_by": "buyer"
},
"request_id": "req_biz_003"
}
OTP Verification Errors:
{
"detail": "OTP verification failed",
"error_code": "INVALID_OTP",
"context": {
"phone_number": "+256700000000",
"attempts_remaining": 2,
"expires_at": "2024-12-07T15:45:00Z"
},
"request_id": "req_otp_004"
}
Error Handling Best Practices
-
Always check status codes before processing responses
-
Log request_id for support and debugging purposes
-
Handle rate limiting with exponential backoff
-
Validate data locally before API calls to reduce errors
-
Implement retry logic for temporary failures (5xx errors)
-
Store error contexts for debugging and user support
Integration Examples
Complete integration examples showing real-world usage patterns.
Python Integration
Complete Escrow Workflow:
import requests
import time
from typing import Dict, List, Optional
class PiaxisEscrowClient:
def __init__(self, api_key: str, client_id: str, base_url: str = "https://api.gopiaxis.com"):
self.api_key = api_key
self.client_id = client_id
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'api-key': api_key,
'X-Piaxis-Client-ID': client_id,
'Content-Type': 'application/json'
})
def request_otp(self, phone_number: str, email: str) -> Dict:
"""Request OTP for unregistered user verification"""
response = self.session.post(f"{self.base_url}/api/request-otp", json={
"phone_number": phone_number,
"email": email
})
response.raise_for_status()
return response.json()
def create_escrow(self, escrow_data: Dict) -> Dict:
"""Create a new escrow with terms"""
response = self.session.post(f"{self.base_url}/api/escrows/", json=escrow_data)
if not response.ok:
print(f"Error creating escrow: {response.json()}")
response.raise_for_status()
return response.json()
def fulfill_term(self, escrow_id: str, term_id: str, fulfillment_data: Dict) -> Dict:
"""Fulfill a specific escrow term"""
url = f"{self.base_url}/api/escrows/{escrow_id}/terms/{term_id}/fulfill"
response = self.session.post(url, json=fulfillment_data)
if not response.ok:
print(f"Error fulfilling term: {response.json()}")
response.raise_for_status()
return response.json()
def get_escrow_status(self, escrow_id: str) -> Dict:
"""Get comprehensive escrow status"""
response = self.session.get(f"{self.base_url}/api/escrows/{escrow_id}/status")
response.raise_for_status()
return response.json()
def release_escrow(self, escrow_id: str, release_data: Dict) -> Dict:
"""Release escrow funds"""
response = self.session.post(f"{self.base_url}/api/escrows/{escrow_id}/release", json=release_data)
if not response.ok:
print(f"Error releasing escrow: {response.json()}")
response.raise_for_status()
return response.json()
def reverse_escrow(self, escrow_id: str, reverse_data: Dict) -> Dict:
"""Reverse escrow payment"""
response = self.session.post(f"{self.base_url}/api/escrows/{escrow_id}/reverse", json=reverse_data)
if not response.ok:
print(f"Error reversing escrow: {response.json()}")
response.raise_for_status()
return response.json()
# Usage example
def complete_escrow_workflow():
client = PiaxisEscrowClient(
api_key="your_api_key_here",
client_id="piaxis_your_client_id"
)
# Step 1: Request OTP for buyer
otp_response = client.request_otp(
phone_number="+256700000000",
email="[email protected]"
)
print("OTP sent to buyer")
# Step 2: Create escrow (assume buyer enters OTP)
escrow_data = {
"receiver_id": "096b723a-45c5-4957-94d7-747835136265",
"amount": "50000.00",
"currency_code": "UGX",
"payment_method": "mtn",
"description": "Electronics purchase with delivery terms",
"terms": [
{
"type": "delivery_confirmation",
"data": {
"description": "Confirm receipt of electronics",
"deadline": "2024-12-14T23:59:59Z"
}
}
],
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "123456" # User-provided OTP
}
}
escrow = client.create_escrow(escrow_data)
escrow_id = escrow["escrow_id"]
term_id = escrow["terms"][0]["term_id"]
print(f"Escrow created: {escrow_id}")
# Step 3: Monitor escrow status
status = client.get_escrow_status(escrow_id)
print(f"Escrow status: {status['status']}")
# Step 4: Fulfill delivery confirmation (buyer confirms)
fulfillment_data = {
"term_type": "delivery_confirmation",
"data": {
"confirmation_method": "confirmation",
"notes": "Package received in perfect condition",
"rating": 5
},
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "789123" # New OTP for fulfillment
}
}
fulfillment = client.fulfill_term(escrow_id, term_id, fulfillment_data)
print("Term fulfilled successfully")
# Step 5: Release funds
release_data = {
"reason": "All terms satisfied - delivery confirmed",
"user_info": {
"email": "[email protected]",
"phone_number": "+256700000000",
"otp": "456789" # New OTP for release
}
}
release = client.release_escrow(escrow_id, release_data)
print(f"Escrow released: {release['release_transaction_id']}")
if __name__ == "__main__":
complete_escrow_workflow()
Node.js Integration
Complete Escrow Management:
const axios = require('axios');
class PiaxisEscrowClient {
constructor(apiKey, clientId, baseUrl = 'https://api.gopiaxis.com') {
this.apiKey = apiKey;
this.clientId = clientId;
this.baseUrl = baseUrl;
this.client = axios.create({
baseURL: baseUrl,
headers: {
'api-key': apiKey,
'X-Piaxis-Client-ID': clientId,
'Content-Type': 'application/json'
}
});
// Add response interceptor for error handling
this.client.interceptors.response.use(
response => response,
error => {
console.error('API Error:', error.response?.data || error.message);
throw error;
}
);
}
async requestOtp(phoneNumber, email) {
const response = await this.client.post('/api/request-otp', {
phone_number: phoneNumber,
email: email
});
return response.data;
}
async createEscrow(escrowData) {
const response = await this.client.post('/api/escrows/', escrowData);
return response.data;
}
async fulfillTerm(escrowId, termId, fulfillmentData) {
const response = await this.client.post(
`/api/escrows/${escrowId}/terms/${termId}/fulfill`,
fulfillmentData
);
return response.data;
}
async getEscrowStatus(escrowId) {
const response = await this.client.get(`/api/escrows/${escrowId}/status`);
return response.data;
}
async releaseEscrow(escrowId, releaseData) {
const response = await this.client.post(
`/api/escrows/${escrowId}/release`,
releaseData
);
return response.data;
}
async reverseEscrow(escrowId, reverseData) {
const response = await this.client.post(
`/api/escrows/${escrowId}/reverse`,
reverseData
);
return response.data;
}
// Utility method to poll escrow status until completion
async waitForTermFulfillment(escrowId, maxWaitTime = 300000) {
const startTime = Date.now();
while (Date.now() - startTime < maxWaitTime) {
const status = await this.getEscrowStatus(escrowId);
if (status.progress.all_terms_met) {
return status;
}
// Wait 10 seconds before next check
await new Promise(resolve => setTimeout(resolve, 10000));
}
throw new Error('Timeout waiting for term fulfillment');
}
}
// Usage example with error handling
async function handleEscrowWorkflow() {
const client = new PiaxisEscrowClient(
'your_api_key_here',
'piaxis_your_client_id'
);
try {
// Create escrow with location verification term
const escrowData = {
receiver_id: "096b723a-45c5-4957-94d7-747835136265",
amount: "75000.00",
currency_code: "UGX",
payment_method: "airtel",
description: "Service delivery with location verification",
terms: [
{
type: "location_verification",
data: {
latitude: 0.347596,
longitude: 32.582520,
radius: 100,
description: "Verify service location"
}
}
],
user_info: {
email: "[email protected]",
phone_number: "+256700000000",
otp: "123456"
}
};
const escrow = await client.createEscrow(escrowData);
console.log('Escrow created:', escrow.escrow_id);
// Monitor for fulfillment
console.log('Waiting for term fulfillment...');
const completedStatus = await client.waitForTermFulfillment(escrow.escrow_id);
console.log('All terms fulfilled!');
// Auto-release escrow
const releaseData = {
reason: "Location verified successfully - auto-release",
merchant_authorization: true
};
const release = await client.releaseEscrow(escrow.escrow_id, releaseData);
console.log('Escrow released:', release.release_transaction_id);
} catch (error) {
console.error('Escrow workflow failed:', error.response?.data || error.message);
// Handle specific error cases
if (error.response?.status === 422) {
console.log('Validation errors:', error.response.data.errors);
} else if (error.response?.status === 429) {
console.log('Rate limited - waiting before retry');
// Implement retry logic
}
}
}
module.exports = { PiaxisEscrowClient };
Best Practices
Security Best Practices
-
API Key Management: - Store API keys securely (environment variables, key vaults) - Rotate API keys regularly - Use different keys for different environments - Never commit API keys to version control
-
Authentication Flow: - Validate OTP expiration times - Implement proper session management - Use HTTPS for all API communications - Validate user permissions before operations
-
Data Validation: - Validate all inputs client-side and server-side - Sanitize user-provided data - Implement proper error handling - Log security-relevant events
Performance Best Practices
-
Request Optimization: - Batch operations when possible - Implement caching for frequently accessed data - Use appropriate timeouts - Handle rate limiting gracefully
-
Error Handling: - Implement exponential backoff for retries - Log detailed error information - Provide meaningful error messages to users - Monitor error rates and patterns
-
Monitoring: - Track escrow completion rates - Monitor API response times - Set up alerts for high error rates - Analyze term fulfillment patterns
Operational Best Practices
-
Escrow Lifecycle Management: - Set appropriate term deadlines - Monitor pending escrows regularly - Implement automated release for simple terms - Handle dispute resolution processes
-
User Experience: - Provide clear term descriptions - Send status update notifications - Implement progress tracking - Offer customer support integration
-
Business Logic: - Design terms that are easily verifiable - Implement fair dispute resolution - Consider regional payment preferences - Plan for edge cases and exceptions
Testing and Validation
-
Integration Testing: - Test all payment methods - Validate term fulfillment flows - Test error scenarios - Verify webhook delivery
-
User Acceptance Testing: - Test with real user scenarios - Validate mobile device compatibility - Test network connectivity edge cases - Verify OTP delivery across carriers
-
Production Readiness: - Implement comprehensive logging - Set up monitoring and alerting - Plan for disaster recovery - Document operational procedures
Troubleshooting Guide
Common Issues and Solutions:
Issue: OTP not received Solution: - Check phone number format - Verify carrier compatibility - Implement alternative delivery methods - Check OTP expiration times
Issue: Term fulfillment failures Solution: - Validate location accuracy requirements - Check device permissions - Verify user authentication - Review term-specific requirements
Issue: High escrow reversal rates Solution: - Review term clarity and fairness - Improve product/service descriptions - Implement better dispute resolution - Analyze reversal reasons
Issue: Performance problems Solution: - Check API rate limits - Optimize request patterns - Implement proper caching - Monitor database performance
Support and Resources
-
API Documentation: https://docs.gopiaxis.com/api
-
Developer Support: developers@piaxis.com
-
Status Page: https://status.gopiaxis.com
-
Community Forum: https://community.gopiaxis.com
-
Webhook Testing: Use webhook testing tools for development
-
Postman Collection: Available for API testing
Emergency Contact: For critical issues affecting production systems, contact support@piaxis.com with “URGENT” in the subject line.