# API Request Authentication Source: https://docs.juicyway.com/authentication Authenticate your API calls to Payment related endpoints. Before proceeding with authentication, make sure you've completed the [Quickstart](/quickstart) guide and set up your [Webhooks](/webhooks). ## Authentication Headers Authenticate your API calls by including your gateway key in the `Authorization` header of every request you make to the payment endpoints. Generally, we provide both test and live keys. `test` keys are meant to be used from your **sandbox** when integrating Juice API. The `live` keys, however, are to be kept **secret**. **`Both test and live keys have the format: myusdguyheiuwX746bagbedjyqg, but sandbox keys will not be the same as the production keys.`** Authorization headers should be in the following format: `Authorization: API_KEY` **Sample Authorization Header** ```bash theme={null} Authorization: test_r3m3mb3r2pu70nasm1l3 ``` API requests made without authentication will fail with the status code `401: Unauthorized`. See our [Errors](/errors) page for details on handling authentication errors. All API requests must be made over HTTPS. ## API Key Management ### Key Types * **Test Keys**: Used in the sandbox environment for integration testing * **Live Keys**: Used in production for processing real transactions * **Restricted Keys**: Limited-scope keys for specific operations ### Key Security Best Practices Never commit your API keys to git repositories or expose them in client-side code. Your live production key must be kept secure at all times. 1. **Environment Variables**: Store API keys as environment variables rather than hardcoding them ```bash theme={null} # .env file JUICE_API_KEY=live_myusdguyheiuwX746bagbedjyqg ``` 2. **Secure Configuration**: Use secure configuration management services in production ```javascript theme={null} // Node.js example using environment variables const apiKey = process.env.JUICE_API_KEY; ``` 3. **Key Rotation**: Implement a regular key rotation schedule * Rotate keys every 90 days * Generate new keys before deactivating old ones * Update all systems using the keys during maintenance windows Keep old keys active for a short overlap period (maximum 24 hours) during transition to prevent service disruption. * Read about [Error Handling](/errors) to properly handle authentication errors * Explore the Payment APIs to start processing transactions * Set up your production environment with live keys # Create Customer Source: https://docs.juicyway.com/customers/create-customer Create and manage customers within your integration. ## Overview The Customers API enables you to create and manage customer profiles for your integration. Each customer object includes personal information, contact details, and billing information that can be referenced in future transactions. ## Create a Customer ```json theme={null} POST /customers ``` Create a new customer profile with the specified information. Each customer must have a unique email address within your integration. Ensure phone numbers match the billing address country format. For example, Nigerian phone numbers (+234) should have a Nigerian billing address. ### Request Parameters Customer's first name. * Maximum length: 100 characters * Must contain only letters, spaces, hyphens, and apostrophes Customer's last name. * Maximum length: 100 characters * Must contain only letters, spaces, hyphens, and apostrophes Customer's email address. * Must be a valid email format * Must be unique within your integration Customer's phone number in E.164 format. * Must include country code * Must be a valid number for the billing address country * Example: +2348012345678 Customer's billing address information. Street address (first line) * Maximum length: 100 characters Street address (second line) * Maximum length: 100 characters City name * Maximum length: 50 characters State or province * Maximum length: 50 characters Postal or ZIP code * Format varies by country Two-letter country code (ISO 3166-1 alpha-2) * Example: "US", "NG", "GB" Must be of `business` or `individual` ### Code Examples ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/customers" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348012345678", "type": "business|individual", "billing_address": { "line1": "123 Test Lane", "line2": "Suite 456", "city": "Lagos", "state": "Lagos", "zip_code": "100001", "country": "NG" } }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.spendjuice.com/customers', { method: 'POST', headers: { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ first_name: 'John', last_name: 'Doe', email: 'john.doe@example.com', phone_number: '+2348012345678', type: "business|individual", billing_address: { line1: '123 Test Lane', line2: 'Suite 456', city: 'Lagos', state: 'Lagos', zip_code: '100001', country: 'NG' } }) }); const customer = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.spendjuice.com/customers', headers={ 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' }, json={ 'first_name': 'John', 'last_name': 'Doe', 'email': 'john.doe@example.com', 'phone_number': '+2348012345678', 'type': 'business|individual', 'billing_address': { 'line1': '123 Test Lane', 'line2': 'Suite 456', 'city': 'Lagos', 'state': 'Lagos', 'zip_code': '100001', 'country': 'NG' } } ) customer = response.json() ``` ### Response ```json 201 Success theme={null} { "data": { "id": "6f7e1e7f-93d1-4fcc-b7a4-738f869615c8", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348012345678", "type": "business|individual", "billing_address": { "line1": "123 Test Lane", "line2": "Suite 456", "city": "Lagos", "state": "Lagos", "zip_code": "100001", "country": "NG" } } } ``` ```json 400 Validation Error theme={null} { "error": { "code": "validation_error", "message": "Invalid input parameters", "details": { "email": ["Invalid email format"], "phone_number": ["Phone number does not match country format"] } } } ``` ```json 409 Duplicate Customer theme={null} { "error": { "code": "duplicate_customer", "message": "A customer with this email already exists", "details": { "email": ["must be unique"] } } } ``` ## Rate Limits | Environment | Requests per minute | | ----------- | ------------------- | | Test | 100 | | Production | 1000 | Exceeding these limits will return a `429 Too Many Requests` response. ## Idempotency All POST requests support idempotency to prevent duplicate customer creation. Include an `Idempotency-Key` header with a unique value for each request: ```bash theme={null} Idempotency-Key: a123b456-c789-d012-e345-f67890123456 ``` The same key will return the original response for duplicate requests within 24 hours. ## Best Practices 1. **Validation** * Validate email formats before sending * Ensure phone numbers match country codes * Use proper character encoding for names 2. **Error Handling** * Implement retry logic with exponential backoff * Handle validation errors gracefully * Check for duplicate customers before creation 3. **Security** * Use HTTPS for all API calls * Keep API keys secure * Implement proper access controls For support with customer creation: * Check our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Delete Customer Source: https://docs.juicyway.com/customers/delete-customer Permanently remove a customer record from your integration Customer deletion is a permanent, irreversible action. Make sure to confirm the deletion intent and understand the implications before proceeding. ## Delete a Customer ```http theme={null} DELETE /customers/{customer_id} ``` Delete a customer and all associated data. This action cannot be undone. ### Parameters The unique identifier of the customer to delete ### Cascade Deletion Behavior When you delete a customer, the following associated data will also be permanently removed: * Customer profile information * Saved payment methods * Billing addresses * Transaction history references * Subscription associations Transaction records themselves are preserved for compliance and audit purposes, even after customer deletion. ### Data Retention Policy After deletion: * Customer data is immediately removed from active systems * Backups are retained for 30 days as per our data retention policy * Transaction records are maintained in compliance with financial regulations * Anonymized analytics data may be retained ## Request Examples ```bash cURL theme={null} curl -X DELETE "https://api.spendjuice.com/v1/customers/cus_12345" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await juice.customers.delete('cus_12345'); ``` ```python Python theme={null} response = juice.Customer.delete('cus_12345') ``` ```php PHP theme={null} $response = $juice->customers->delete('cus_12345'); ``` ## Response A successful deletion returns an HTTP `204 No Content` response with no response body. ## Error Scenarios ```json theme={null} { "error": { "code": "customer_not_found", "message": "No customer found with ID: cus_12345", "type": "not_found_error" } } ``` ```json theme={null} { "error": { "code": "deletion_restricted", "message": "Cannot delete customer with active subscriptions", "type": "authorization_error" } } ``` ```json theme={null} { "error": { "code": "deletion_conflict", "message": "Customer has pending transactions", "type": "conflict_error" } } ``` ## Recommended Deletion Workflow Check for any active subscriptions, pending transactions, or other dependencies that might prevent deletion. Consider exporting customer data before deletion if needed for records. Implement a confirmation step in your interface to prevent accidental deletions. Perform the deletion API call with proper error handling. Confirm the customer record has been removed by attempting to fetch it. ## Best Practices * Implement confirmation workflows for deletion requests * Handle cascade deletion effects in your application * Maintain audit logs of deletion operations * Consider soft deletion for recoverable data * Respect data privacy regulations (GDPR, CCPA) If you need to preserve customer data for compliance or business purposes, consider implementing a soft delete mechanism instead of permanent deletion. # Fetch Customer Source: https://docs.juicyway.com/customers/fetch-customer Retrieve details of a specific customer by their ID ## Overview Retrieve detailed information about a specific customer using their unique identifier. This endpoint supports field selection, response versioning, and conditional fetching. ## Base URL ```bash theme={null} GET /customers/{id} ``` ## Path Parameters The unique identifier of the customer. Example: `6f7e1e7f-93d1-4fcc-b7a4-738f869615c8` ## Query Parameters Comma-separated list of fields to include in the response. Example: `fields=first_name,email,phone_number` API version for backwards compatibility. Default: Latest version Additional related resources to include. Example: `include=transactions,payment_methods` ## Request Examples ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/customers/6f7e1e7f-93d1-4fcc-b7a4-738f869615c8" \ -H "Authorization: YOUR_API_KEY" \ -H "Accept: application/json" ``` ```javascript Node.js theme={null} const axios = require('axios'); try { const response = await axios.get( 'https://api.spendjuice.com/customers/6f7e1e7f-93d1-4fcc-b7a4-738f869615c8', { headers: { 'Authorization': ' YOUR_API_KEY', 'Accept': 'application/json' } } ); console.log(response.data); } catch (error) { console.error('Error fetching customer:', error.response.data); } ``` ```python Python theme={null} import requests headers = { 'Authorization': ' YOUR_API_KEY', 'Accept': 'application/json' } try: response = requests.get( 'https://api.spendjuice.com/customers/6f7e1e7f-93d1-4fcc-b7a4-738f869615c8', headers=headers ) response.raise_for_status() print(response.json()) except requests.exceptions.RequestException as e: print('Error fetching customer:', e) ``` ## Response ```json 200 Success theme={null} { "data": { "id": "6f7e1e7f-93d1-4fcc-b7a4-738f869615c8", "first_name": "Test", "last_name": "Customer", "email": "test@custom.com", "phone_number": "+2348012345678", "billing_address": { "line1": "123 Test lane", "line2": "3456 Mike Drive", "city": "Anon", "state": "Acme", "zip_code": "12345", "country": "US" }, "created_at": "2024-03-15T12:00:00Z", "updated_at": "2024-03-15T12:00:00Z" } } ``` ```json 404 Not Found theme={null} { "error": { "code": "customer_not_found", "message": "No customer found with ID: 6f7e1e7f-93d1-4fcc-b7a4-738f869615c8" } } ``` ## Rate Limiting This endpoint has a rate limit of 1000 requests per hour per API key. Rate limit information is included in the response headers: * `X-RateLimit-Limit`: Total requests allowed per hour * `X-RateLimit-Remaining`: Remaining requests in the current period * `X-RateLimit-Reset`: Time when the rate limit resets (Unix timestamp) ## Common Use Cases ```bash theme={null} GET /customers/{id}?fields=first_name,last_name,email ``` Returns only the customer's basic contact information. ```bash theme={null} GET /customers/{id}?include=transactions,payment_methods ``` Returns customer details along with their transaction history and saved payment methods. ```bash theme={null} GET /customers/{id}?version=2023-01-01 ``` Returns customer data formatted according to the specified API version. ## Error Responses | Status Code | Description | | ----------- | -------------------------------------------------- | | 400 | Invalid request (malformed parameters) | | 401 | Authentication failed (invalid or missing API key) | | 403 | Permission denied | | 404 | Customer not found | | 429 | Rate limit exceeded | | 500 | Internal server error | ## Best Practices 1. Always use HTTPS for API requests 2. Implement proper error handling 3. Cache responses when appropriate 4. Monitor rate limits 5. Use field selection to minimize response payload size For additional assistance: * Check our [API Reference](/api-reference/overview) * Contact [Support](mailto:support@juicyway.com) # List Customers Source: https://docs.juicyway.com/customers/list-customers Retrieve and filter a paginated list of customers Retrieve a list of customers with support for pagination, filtering, and sorting. ## Endpoint ```bash theme={null} GET /customers ``` ## Query Parameters Number of records to return per page (max: 100) Cursor for fetching next page of results Cursor for fetching previous page of results Filter customers by email address Filter customers created after this timestamp (ISO 8601) Filter customers created before this timestamp (ISO 8601) Sort order for results (created\_at:asc|created\_at:desc) ## Response Format Array of customer objects. See [Customer Object](#customer-object) for structure. Cursor for the previous page Cursor for the next page Number of records per page ## Examples ### Basic List Request ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/customers?limit=2" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const juice = require('juice-node'); const client = new juice('YOUR_API_KEY'); const customers = await client.customers.list({ limit: 2 }); ``` ```python Python theme={null} import juice juice.api_key = 'YOUR_API_KEY' customers = juice.Customer.list( limit=2 ) ``` ```json Response theme={null} { "data": [ { "id": "6f7e1e7f-93d1-4fcc-b7a4-738f869615c8", "first_name": "Test", "last_name": "Customer", "email": "test@custom.er", "phone_number": "+2348012345678", "billing_address": { "line1": "123 Test lane", "line2": "356 Mike Drive", "city": "Anon", "state": "Acme", "zip_code": "12345", "country": "US" }, "created_at": "2024-03-01T12:00:00Z", "updated_at": "2024-03-01T12:00:00Z" }, { "id": "7a8b9c0d-1e2f-3g4h-5i6j-7k8l9m0n1o2p", "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "phone_number": "+2348012345679", "billing_address": { "line1": "456 Sample St", "line2": null, "city": "Lagos", "state": "LA", "zip_code": "23401", "country": "NG" }, "created_at": "2024-03-02T12:00:00Z", "updated_at": "2024-03-02T12:00:00Z" } ], "pagination": { "before": null, "after": "7a8b9c0d-1e2f-3g4h-5i6j-7k8l9m0n1o2p", "limit": 2 } } ``` ### Filtered List Request ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/customers?email=test@custom.er&created_after=2024-01-01T00:00:00Z" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const customers = await client.customers.list({ email: 'test@custom.er', created_after: '2024-01-01T00:00:00Z' }); ``` ```python Python theme={null} customers = juice.Customer.list( email='test@custom.er', created_after='2024-01-01T00:00:00Z' ) ``` ## Pagination The API uses cursor-based pagination to handle large collections of customers. To fetch the next page of results: 1. Get the `after` cursor from the pagination object 2. Pass it as the `after` parameter in your next request 3. Repeat until no more `after` cursor is returned For optimal performance, we recommend: * Use reasonable page sizes (15-50 records) * Cache results when possible * Implement progressive loading in your UI ## Error Responses Invalid query parameters or malformed request Missing or invalid API key Insufficient permissions to list customers ## Rate Limits List operations are subject to the following rate limits: * 100 requests per minute per API key * 1000 requests per hour per API key Exceeding these limits will result in a `429 Too Many Requests` response. ## Best Practices 1. **Efficient Filtering**: Use filters to reduce response size and improve performance 2. **Cursor Management**: Store cursors temporarily for pagination 3. **Bulk Operations**: Use higher limit values for bulk data retrieval 4. **Error Handling**: Implement proper retry logic for rate limits 5. **Data Freshness**: Consider implementing cache invalidation strategies ## Customer Object See the [Customer Object](/snippets/customer-object.mdx) documentation for detailed field descriptions. # Update Customer Source: https://docs.juicyway.com/customers/update-customer Update an existing customer's information ## Overview The customer update endpoint allows you to modify existing customer information. You can perform both partial and full updates to customer records. ## Base URL ```bash theme={null} PATCH /customers/{id} ``` ## Authentication All requests must include your API key in the Authorization header: ```bash theme={null} Authorization: YOUR_API_KEY ``` ## Request Parameters ### Path Parameters The unique identifier of the customer to update ### Body Parameters Customer's first name Customer's last name Customer's email address. Must be a valid email format. Customer's phone number in E.164 format (e.g., +2348012345678) Customer's billing address information Primary address line Secondary address line (optional) City name State or province Postal or ZIP code Two-letter country code (ISO 3166-1 alpha-2) ## Examples ```bash cURL theme={null} curl -X PATCH "https://api.spendjuice.com/customers/6f7e1e7f-93d1-4fcc-b7a4-738f869615c8" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone_number": "+2348012345678", "billing_address": { "line1": "123 Test lane", "city": "Anon" } }' ``` ```python Python theme={null} import requests url = "https://api.spendjuice.com/customers/6f7e1e7f-93d1-4fcc-b7a4-738f869615c8" headers = { "Authorization": " YOUR_API_KEY", "Content-Type": "application/json" } data = { "phone_number": "+2348012345678", "billing_address": { "line1": "123 Test lane", "city": "Anon" } } response = requests.patch(url, headers=headers, json=data) print(response.json()) ``` ```javascript Node.js theme={null} const axios = require('axios'); const customerUpdate = async () => { try { const response = await axios.patch( 'https://api.spendjuice.com/customers/6f7e1e7f-93d1-4fcc-b7a4-738f869615c8', { phone_number: '+2348012345678', billing_address: { line1: '123 Test lane', city: 'Anon' } }, { headers: { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } } ); return response.data; } catch (error) { console.error('Error updating customer:', error.response.data); } }; ``` ## Response ### Success Response (200 OK) ```json theme={null} { "data": { "id": "6f7e1e7f-93d1-4fcc-b7a4-738f869615c8", "first_name": "Test", "last_name": "Customer", "email": "test@custom.er", "phone_number": "+2348012345678", "billing_address": { "line1": "123 Test lane", "line2": "3456 Mike Drive", "city": "Anon", "state": "Acme", "zip_code": "12345", "country": "US" } } } ``` ### Error Responses ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid parameters provided", "details": { "phone_number": ["Invalid phone number format"] } } } ``` ```json theme={null} { "error": { "code": "not_found", "message": "Customer not found" } } ``` ```json theme={null} { "error": { "code": "validation_error", "message": "The request contains invalid parameters", "details": { "email": ["Invalid email format"] } } } ``` ## Update Rules * Only provide fields that need to be updated * Nested objects (like billing\_address) must be updated as a complete object * Empty strings ("") will clear the field value * Null values are ignored * Phone numbers must be in E.164 format * Email addresses must be valid format ## Rate Limits Customer update requests are limited to: * 10 requests per minute per API key * 1000 requests per day per API key ## Versioning The current version of this API is v1. We recommend including a version accept header: ```bash theme={null} Accept: application/json;version=1 ``` ## Best Practices 1. **Partial Updates** * Only send fields that need to be changed * Use PATCH for partial updates * Validate data before sending 2. **Error Handling** * Implement proper error handling * Validate response status codes * Log failed update attempts 3. **Idempotency** * Use idempotency keys for critical updates * Retry failed requests with the same idempotency key 4. **Validation** * Validate all input fields client-side * Handle validation errors appropriately * Check response data matches expected format For additional support: * Check our [API Reference](/api-reference/overview) * Contact [Support](mailto:support@juicyway.com) * Join our [Developer Community](https://discord.gg/juice) # Errors Source: https://docs.juicyway.com/errors Learn how to handle errors when integrating with the Juice API ## HTTP Status Codes Here are the common HTTP status codes you may encounter when using our API: ### 200 - Success The request was successful, and the intended action was completed. For charge or verification requests, always check the `data` object to confirm the specific outcome (success or failure). ### 201 - Created A new resource was successfully created. ### 204 - No Content The request was successful, but no content is returned in the response. ### 400 - Bad Request A validation or client-side error occurred, preventing the request from being processed. ### 401 - Unauthorized The request was not authorized. This commonly occurs due to: * Invalid secret key in authorization header * Missing authorization header * Expired API key * Using test key in production environment * Using production key in test environment ### 403 - Forbidden Access to the requested resource is denied due to insufficient permissions. ### 404 - Not Found The requested resource could not be found. This status code does not apply when a payment session is completed. ### 422 - Unprocessable Entity Some required fields are missing or invalid, preventing the request from being processed. ### 429 - Too Many Requests You've exceeded the API rate limits. ### 500 - Server Error The request could not be fulfilled due to an error on Juicyway's server. Please report any encounters with 500 errors to our support team. ## Error Response Format All API errors follow a consistent format: ```json theme={null} { "error": { "code": "error_code", "message": "Human readable error message", "type": "error_type", "details": { // Additional error context if available } } } ``` ## Common Error Types ### Validation Errors When required fields are missing or invalid: ```json theme={null} { "error": { "code": "validation_error", "message": "The request was invalid", "type": "invalid_request_error", "errors": [ { "field": "amount", "message": "Amount must be a positive integer" }, { "field": "currency", "message": "Currency must be one of: NGN, USD, CAD" } ] } } ``` ### Authentication Errors When there are issues with API keys or authentication: ```json theme={null} { "error": { "code": "invalid_key", "message": "Invalid API key provided", "type": "authentication_error" } } ``` ### Rate Limiting Errors When you exceed the API rate limits: ```json theme={null} { "error": { "code": "rate_limit_exceeded", "message": "Too many requests. Please try again in 30 seconds.", "type": "rate_limit_error", "retry_after": 30 } } ``` ### Server Errors For 500-level server errors: ```json theme={null} { "error": { "code": "internal_server_error", "message": "An unexpected error occurred", "type": "server_error", "request_id": "req_123xyz" } } ``` ## Error Handling Best Practices ### Timeout Handling All API requests automatically timeout after 30 seconds. For long-running operations like payments that may take longer to process, we recommend: 1. Implementing proper retry logic with exponential backoff 2. Using webhooks to receive the final status asynchronously 3. Checking the transaction status via the GET endpoints if webhook delivery fails ### Rate Limit Handling To handle rate limits effectively: 1. Implement exponential backoff with jitter for retries 2. Check the `retry_after` header to know when to retry 3. Cache frequently requested data 4. Batch requests where possible ### Server Error Handling Best practices for handling server errors: 1. Log the `request_id` for debugging 2. Implement retry logic with exponential backoff 3. Contact support if errors persist 4. Set up monitoring for error rates ## Code Examples Here's how to properly handle API errors in different languages: ```javascript theme={null} try { const response = await juiceApi.createPayment({ amount: 1000, currency: 'NGN' }); } catch (error) { if (error.type === 'validation_error') { // Handle validation errors error.errors.forEach(err => { console.log(`${err.field}: ${err.message}`); }); } else if (error.type === 'authentication_error') { // Handle auth errors console.log('Please check your API keys'); } else if (error.type === 'rate_limit_error') { // Implement exponential backoff const retryAfter = error.retry_after || 30; await sleep(retryAfter * 1000); // Retry request } else { // Handle other errors console.error(`Error: ${error.message}`); // Log error for debugging console.error(`Request ID: ${error.request_id}`); } } ``` ```python theme={null} try: response = juice_api.create_payment( amount=1000, currency='NGN' ) except ValidationError as e: # Handle validation errors for error in e.errors: print(f"{error['field']}: {error['message']}") except AuthenticationError as e: # Handle auth errors print("Please check your API keys") except RateLimitError as e: # Implement exponential backoff retry_after = getattr(e, 'retry_after', 30) time.sleep(retry_after) # Retry request except ServerError as e: # Handle server errors print(f"Error: {e.message}") # Log error for debugging print(f"Request ID: {e.request_id}") except Exception as e: # Handle unexpected errors print(f"Unexpected error: {str(e)}") ``` # Add Contact Source: https://docs.juicyway.com/exchange/market-makers/add-contact Add a contact to a market maker. ```json theme={null} PATCH /exchange/market-makers/{id}/add-contact ``` **Parameters:** * `id` (string, required): The unique ID of the market maker. * `email` (string, required): Contact email. * `id` (string, required): Contact ID. * `name` (string, required): Contact name. * `type` (string, required): Contact type (`user` or `business`). **Sample Request** ```bash theme={null} curl -X PATCH "https://exchange.spendjuice.com/v1/exchange/market-makers/7da75a46-a1bc-11ee-9a32-560f156a658b/add-contact" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email": "new@user.com", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "name": "New User", "type": "user" }' ``` **Sample Response** ```json theme={null} { "data": { "beneficiary": { "account_name": "MICHAEL ENITAN ASAJU", "account_number": "0821081314", "account ``` # Create a Market Maker Source: https://docs.juicyway.com/exchange/market-makers/create-market-makers The endpoint below creates a new market maker for the exchange. ```json theme={null} POST /exchange/market-makers ``` #### **Request** * **Headers**: `Authorization: YOUR_API_KEY` * **Body** (required): * **Media Type**: `application/json` ```json theme={null} { "business_id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "contacts": [ { "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "type": "user" } ], "swap_provider": true, "swap_weight": 50 } ``` ### **Fields:** * `business_id` (string, required): The ID of the business to be assigned as a market maker. * `contacts `(array of objects, required): A list of associated contact users. * `id `(string, required): Contact user ID. * `type `(string, required): The type of contact (e.g., user). * `swap_provider` (boolean, required): Indicates if the market maker provides swaps. * `swap_weight` (integer, required): The weight or priority for the swap service (e.g., 0–100). #### **Responses:** **201 Created** 1. **Media Type**: `application/json` 2. **Sample Response**: ```json theme={null} { "data": { "archived": false, "contacts": [ { "email": "test@user.com", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "name": "Test User", "type": "user" } ], "email": "anon@nymous.com", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "name": "Anon Nymous", "swap_provider": false, "swap_weight": 0 } } ``` * **400 Bad Request**- Returned if the request contains invalid data. * **403 Forbidden**- Returned if the user is not authorized to create a market maker. * **422 Unprocessable Entity**- Returned if required fields are missing or invalid. # Get Market Maker Source: https://docs.juicyway.com/exchange/market-makers/get-market-makers Retrieve details of a specific market maker by ID. ```json theme={null} GET /exchange/market-makers/{id} ``` **Parameters:** * `id` (string, required): The unique ID of the market maker. **Sample Request** ```bash theme={null} curl -X GET "https://exchange.spendjuice.com/v1/exchange/market-makers/7da75a46-a1bc-11ee-9a32-560f156a658b" \ -H "Authorization: YOUR_API_KEY" ``` **Sample Response** ```json theme={null} { "data": { "archived": false, "contacts": [ { "email": "test@user.com", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "name": "Test User", "type": "user" } ], "email": "anon@nymous.com", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "name": "Anon Nymous", "swap_provider": true, "swap_weight": 50 } } ``` # Market Makers Source: https://docs.juicyway.com/exchange/market-makers/list-market-makers Market makers facilitate liquidity on the exchange by providing buy and sell quotes for specific trading pairs. This section outlines how to interact with market maker data via API. The endpoint below lists all available market makers. ``` GET /exchange/market-makers ``` #### **Parameters** * **`before`** *(string, optional)*: Cursor for retrieving records before a specific entry. * **`after`** *(string, optional)*: Cursor for retrieving records after a specific entry. * **`limit`** *(integer, optional)*: Maximum number of records to return. Default: 15. #### **Responses** 1. **200 OK** * **Media Type**: `application/json` * **Sample Response**: ```json theme={null} { "data": [ { "archived": false, "contacts": [ { "email": "test@user.com", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "name": "Test User", "type": "user" } ], "email": "anon@nymous.com", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "name": "Anon Nymous", "swap_provider": false, "swap_weight": 0 } ], "pagination": { "after": "b101f718-d133-450c-a572-c281c7341803", "before": null, "limit": 15 } } ``` # Remove Contact Source: https://docs.juicyway.com/exchange/market-makers/remove-contact Remove a contact from a market maker. ```json theme={null} PATCH /exchange/market-makers/{id}/remove-contact ``` **Parameters:** * `id` (string, required): The unique ID of the market maker. * `contact_id` (string, required): The ID of the contact to remove. **Sample Request** ```json theme={null} curl -X PATCH "https://exchange.spendjuice.com/v1/exchange/market-makers/7da75a46-a1bc-11ee-9a32-560f156a658b/remove-contact" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contact_id": "7da8e726-a1bc-11ee-80cf-560f156a658b" }' ``` **Sample Response** ```json theme={null} { "data": { "archived": true, "contacts": [], "email": "anon@nymous.com", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "name": "Anon Nymous", "swap_provider": false, "swap_weight": 0 } } ``` # Update Market Maker Source: https://docs.juicyway.com/exchange/market-makers/update-market-maker Update an existing market maker. ```json theme={null} PATCH /exchange/market-makers/{id} ``` **Parameters:** * `id` (string, required): The unique ID of the market maker to update. * `archived` (boolean, optional): Whether the market maker is archived. * `swap_provider` (boolean, optional): Whether the market maker is a swap provider. * `swap_weight` (integer, optional): Swap weight. **Sample Request** ```bash theme={null} curl -X PATCH "https://exchange.spendjuice.com/v1/exchange/market-makers/7da75a46-a1bc-11ee-9a32-560f156a658b" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "archived": true, "swap_provider": false, "swap_weight": 0 }' ``` **Sample Response** ```json theme={null} { "data": { "archived": true, "contacts": [ { "email": "test@user.com", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "name": "Test User", "type": "user" } ], "email": "anon@nymous.com", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "name": "Anon Nymous", "swap_provider": false, "swap_weight": 0 } } ``` # Cancel Order Source: https://docs.juicyway.com/exchange/orders/cancel-order Cancel an existing order. ```json theme={null} PUT /exchange/orders/{id}/cancel ``` **Parameters:** * `id` (string, required): The unique ID of the order to cancel. **Sample Request** ```bash theme={null} curl -X PUT "https://exchange.spendjuice.com/v1/exchange/orders/7da75a46-a1bc-11ee-9a32-560f156a658b/cancel" \ -H "Authorization: YOUR_API_KEY" ``` **Sample Response** ```json theme={null} { "data": { "accepted_at": "2023-12-23T17:55:42.919523", "average_fill_price": 80000, "business_id": "dd625bec-b1a3-466e-867e-c91ae0b6e71e", "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.911", "expires_at": null, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "min_qty": null, "min_quote_qty": null, "percent_filled": 10000, "price": 80000, "price_type": "market", "qty": 1.0, "quote_qty": null, "status": "cancelled", "symbol": "USD-NGN", "time_in_force": "gtc", "trades": [], "type": "buy", "updated_at": "2023-12-23T17:55:42.911", "user_id": "b101f718-d133-450c-a572-c281c7341803" } } ``` # Create Orders Source: https://docs.juicyway.com/exchange/orders/create-order Create a new order. ```json theme={null} POST /exchange/orders ``` **Parameters:** * `qty` (number, required): Order quantity in the base currency. * `symbol` (string, required): Currency pair symbol (e.g., `USD-NGN`). * `type` (string, required): Order type (`buy` or `sell`). * `price` (integer, optional): Order price in minor units. * `price_type` (string, optional): Price type (`limit` or `market`). * `time_in_force` (string, optional): Time in force (`gtc`, `gtt`, `ioc`, `fok`). **Sample Request** ```bash theme={null} curl -X POST "https://exchange.spendjuice.com/v1/exchange/orders" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "qty": 1.0, "symbol": "USD-NGN", "type": "buy" }' ``` **Sample Response** ```json theme={null} { "data": { "accepted_at": "2023-12-23T17:55:42.919523", "average_fill_price": 80000, "business_id": "dd625bec-b1a3-466e-867e-c91ae0b6e71e", "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.911", "expires_at": null, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "min_qty": null, "min_quote_qty": null, "percent_filled": 10000, "price": 80000, "price_type": "market", "qty": 1.0, "quote_qty": null, "status": "filled", "symbol": "USD-NGN", "time_in_force": "gtc", "trades": [ { "buy_order_id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "commission": 0, "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.921", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "price": 80000, "sell_order_id": "7d97c0b8-a1bc-11ee-b240-560f156a658b", "size": 1.0, "symbol": "USD-NGN" } ], "type": "buy", "updated_at": "2023-12-23T17:55:42.911", "user_id": "b101f718-d133-450c-a572-c281c7341803" } } ``` # Get Order Book Source: https://docs.juicyway.com/exchange/orders/get-order-book Retrieve the order book for a specific currency pair. ```json theme={null} GET /exchange/books/{symbol} ``` **Parameters:** * `symbol` (string, required): The currency pair symbol (e.g., `USD-NGN`). **Sample Request** ```bash theme={null} curl -X GET "https://exchange.spendjuice.com/v1/exchange/books/USD-NGN" \ -H "Authorization: YOUR_API_KEY" ``` **Sample Response** ```json theme={null} { "data": { "asks": [ { "business_id": "ce8331b2-a396-46c1-9638-5db5e9cf5b2e", "created_at": "2023-12-23T19:11:23.215", "id": "0fe2d322-a1c7-11ee-9c0e-560f156a658b", "percent_filled": 0, "price": 80000, "price_type": "limit", "status": "open", "time_in_force": "gtc", "total_qty": "1", "unfilled_qty": "1.0", "user_id": null } ], "bids": [ { "business_id": "ce8331b2-a396-46c1-9638-5db5e9cf5b2e", "created_at": "2023-12-23T19:11:23.097", "id": "0fd0baf2-a1c7-11ee-ae88-560f156a658b", "percent_filled": 0, "price": 75000, "price_type": "limit", "status": "open", "time_in_force": "gtc", "total_qty": "1", "unfilled_qty": "1.0", "user_id": "82dde615-d181-4f3e-8d3f-53ac7962feb7" } ], "max_bid": 75000, "min_ask": 80000, "symbol": "USD-NGN" } } ``` # List Orders Source: https://docs.juicyway.com/exchange/orders/list-orders Retrieve a list of orders. ```json theme={null} GET /exchange/orders ``` **Parameters:** * `before` (string, optional): Cursor for pagination (before). * `after` (string, optional): Cursor for pagination (after). * `limit` (integer, optional): Limit the number of orders returned. * `type` (string, optional): Filter by order type (`buy` or `sell`). * `status` (string, optional): Filter by order status (`open`, `cancelled`, `rejected`, `filled`, `expired`, `closed`). * `price` (integer, optional): Filter by order price. **Sample Request** ```bash theme={null} curl -X GET "https://exchange.spendjuice.com/v1/exchange/orders?limit=10&type=buy" \ -H "Authorization: YOUR_API_KEY" ``` **Sample Response** ```json theme={null} { "data": [ { "accepted_at": "2023-12-23T17:55:42.919523", "average_fill_price": 80000, "business_id": "dd625bec-b1a3-466e-867e-c91ae0b6e71e", "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.911", "expires_at": null, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "min_qty": null, "min_quote_qty": null, "percent_filled": 10000, "price": 80000, "price_type": "market", "qty": 1.0, "quote_qty": null, "status": "filled", "symbol": "USD-NGN", "time_in_force": "gtc", "trades": [ { "buy_order_id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "commission": 0, "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.921", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "price": 80000, "sell_order_id": "7d97c0b8-a1bc-11ee-b240-560f156a658b", "size": 1.0, "symbol": "USD-NGN" } ], "type": "buy", "updated_at": "2023-12-23T17:55:42.911", "user_id": "b101f718-d133-450c-a572-c281c7341803" } ], "pagination": { "after": "b101f718-d133-450c-a572-c281c7341803", "before": null, "limit": 10 } } ``` # Convert Source: https://docs.juicyway.com/exchange/rates/convert Converts a specified amount from one currency to another. Ensure the `amount` is provided in minor units, and the `from` and `to` fields are valid ISO currency codes. Handle cases where the input parameters are missing or invalid to return a `400 - Bad Request` response. ``` POST /exchange/convert ``` ### Sample Request ```json theme={null} { "amount": 75000, "from": "USD", "to": "NGN" } ``` ### Responses #### 200 - Conversion Result Sample Response ```json theme={null} { "data": { "converted_amount": 100 } } ``` #### 400 - Bad Request Indicates a problem with the request (e.g., missing or invalid parameters). # Create Rates Source: https://docs.juicyway.com/exchange/rates/create-rates This endpoint creates a new exchange rate. ```json theme={null} POST /exchange/rates ``` #### **Request** * **Headers**: `Content-Type: application/json` * **Body** (required): ```json theme={null} { "buy": 100, "pair": "USD-NGN", "sell": 75000, "ttl": 60 } ``` * buy (integer): Buy amount in base currency. * pair (string): Currency pair (e.g., "USD-NGN"). * sell (integer): Sell amount in quote currency. * ttl (integer): Time-to-live for the rate, in seconds. #### **Sample Response** 1. **201 Created** * **Media Type**: `application/json` ```json theme={null} { "data": { "buy": 1200, "created_at": "2025-01-21T11:56:45Z", "entity": { "id": "397752fb-92e6-404a-b6e4-d9d72f1379f9", "type": "business" }, "id": "83b16397-d524-4619-b30f-e5e77b1b8d17", "pair": "USD-NGN", "sell": 1100, "ttl": 60, "updated_at": "2025-01-21T11:56:46Z" } } ``` 1. **422 Unprocessable Entity** * **Media Type**: `application/json` * Indicates validation errors or invalid request parameters. # Delete Rates Source: https://docs.juicyway.com/exchange/rates/delete-rates This endpoint deletes a specified exchange rate by its ID. ```json theme={null} DELETE /exchange/rates/{id} ``` #### **Request** * **Headers**: `Authorization: YOUR_API_KEY` * **Path Parameter**: * **`id`** *(string, required)*: The unique identifier of the rate to delete. **Example**: `3f27a046-314d-457f-b39b-1ec30561353d` #### **Responses** 1. **204 No Content** * Indicates that the rate was successfully deleted. * No response body. 2. **404 Not Found** * **Media Type**: `application/json` * Returned if the specified `id` does not exist or is invalid. # Fetch Rate Source: https://docs.juicyway.com/exchange/rates/fetch-rate Retrieves details of a specific exchange rate by its ID. ```json theme={null} GET /exchange/quote/{id}} ``` #### **Request**\\ **Headers**: `Authorization: YOUR_API_KEY`\ \ **Path Parameter**: * **`id`** *(string, required)*: The unique identifier of the rate to retrieve. **Example**: `3f27a046-314d-457f-b39b-1ec30561353d` #### **Responses** 1. **200 OK** * **Media Type**: `application/json` ```json theme={null} { "data": { "id": "2f939fe5-fb7b-4234-8b73-761a848d13af", "locked": true, "rate": 1500, "symbol": "USD-NGN", "time_to_convert": 10, "time_to_lock": 30, "type": "buy" } } ``` 2. **404 Not Found** * **Media Type**: `application/json` * Returned if the specified `id` does not exist or is invalid. \ **Path Parameter**: * `id` *(string, required)*: The unique identifier of the rate to retrieve. **Example**: `3f27a046-314d-457f-b39b-1ec30561353d` * `.time_to_convert` * **Description**: The Time-To-Live (TTL) of the rate in seconds. * `time_to_lock` * **Description**: The duration (in seconds) before the rate becomes available for locking while it is being unlocked. * `locked` * **Description**: * A locked quote is available for use in a swap within the `time_to_convert` interval. * An unlocked rate will become unavailable after the `time_to_lock` interval. * By default, the quote is locked for authenticated requests. * To prevent locking, add `lock=false` to the quote endpoint parameters. * `type` * **Description**: Specifies the conversion side from the provider's perspective. Possible values are `buy` or `sell`. ## Locking a quote # Exchange Rates Source: https://docs.juicyway.com/exchange/rates/list-rates The endpoint provides a list of currency rates ### Request Details * **Parameters**: None * **Accept Header**: `application/json` ```json theme={null} GET /exchange/rates ``` ### Description of Key Fields * **accepted\_at**: Timestamp when the rate was accepted. * **correlation\_id**: Unique identifier for correlating requests. * **entity**: Contains the entity's `id` and `type` (e.g., "business"). * **price**: Exchange rate in minor units. * **symbol**: The currency pair (e.g., "USD-NGN"). * **status**: Status of the rate (e.g., "filled"). * **trades**: Details of the trades executed for the rate, including `price`, `size`, and associated order IDs. ### Sample Response * **Status Code**: `200` * **Description**: Returns a list of rates with detailed information about each rate and related trades. ```json theme={null} { "data": [ { "buy": 1200, "created_at": "2025-01-21T11:56:45Z", "entity": { "id": "397752fb-92e6-404a-b6e4-d9d72f1379f9", "type": "business" }, "id": "83b16397-d524-4619-b30f-e5e77b1b8d17", "pair": "USD-NGN", "sell": 1100, "ttl": 60, "updated_at": "2025-01-21T11:56:46Z" } ] } ``` # Supported Rates. Source: https://docs.juicyway.com/exchange/rates/list-supported-pairs Retrieves a list of supported currency pairs for exchange. To retrieve the list of supported currency pairs, send a `GET` request to the `/exchange/pairs` endpoint with the `Accept` header set to `application/json`. A successful response (HTTP status code 200) will return the above JSON structure. ```json theme={null} GET /exchange/pairs ``` **Sample Response** ```json theme={null} { "data": [ "USD-NGN" ] } ``` # Update an existing Rate Source: https://docs.juicyway.com/exchange/rates/update-rates Updates an existing exchange rate by its ID. ```json theme={null} PATCH /exchange/rates/{id} ``` #### **Request** * **Headers**: `Authorization: YOUR_API_KEY` * **Path Parameter**: * **`id`** *(string, required)*: The unique identifier of the rate to update. **Example**: `3f27a046-314d-457f-b39b-1ec30561353d` * **Body** (required): * **Media Type**: `application/json` ```json theme={null} { "buy": 100, "sell": 75000, "ttl": 60 } ``` **Fields:** * buy (integer): Updated buy amount in base currency. * sell (integer): Updated sell amount in quote currency. * ttl (integer): Updated time-to-live for the rate, in seconds. #### **Responses** 1. **201 Created** * **Media Type**: `application/json` * **Sample Response:** ```json theme={null} { "data": { "accepted_at": "2023-12-23T17:55:42.919523", "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.911", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "expires_at": null, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "min_qty": null, "min_quote_qty": null, "percent_filled": 10000, "price": 80000, "price_type": "market", "qty": 1, "quote_qty": null, "status": "filled", "symbol": "USD-NGN", "time_in_force": "gtc", "trades": [ { "buy_order_id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "commission": 0, "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2023-12-23T17:55:42.921", "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "price": 80000, "sell_order_id": "7d97c0b8-a1bc-11ee-b240-560f156a658b", "size": 1, "symbol": "USD-NGN" } ], "type": "buy", "updated_at": "2023-12-23T17:55:42.911" } } ``` 1. **404 Not Found** * **Media Type**: `application/json` * Returned if the specified `id` does not exist. 1. **422 Unprocessable Entity** * **Media Type**: `application/json` * Returned if the request body contains invalid or missing parameters. # Create Standing Orders Source: https://docs.juicyway.com/exchange/standing-orders/create-standing-order Create a new standing order. Endpoint ```json theme={null} POST /exchange/standing-orders ``` #### **Request Body:** ```json theme={null} { "qty": 1, "symbol": "USD-NGN", "type": "buy" } ``` #### **Responses:** * **`201`** - Standing Order Created **Sample:** ```json theme={null} { "data": { "archived": false, "created_at": "2023-12-23T17:55:42.911", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "low_watermark_qty": 1, "min_qty": null, "qty": 3, "strict": false, "symbol": "USD-NGN", "type": "buy", "updated_at": "2023-12-23T17:55:42.911" } } ``` * 422 - Unprocessable Entity # Delete Standing Order Source: https://docs.juicyway.com/exchange/standing-orders/delete-standing-order Delete a standing order by its ID. **Endpoint** ```json theme={null} DELETE /exchange/standing-orders/{id} ``` #### **Path Parameters:** * **`id`** (string, required): Standing Order ID. #### **Query Parameters:** * **`token`** (string, optional): Token for additional validation. #### **Responses:** * **`204`** - No Content * **`404`** - Not Found # Retrieve Standing Order Source: https://docs.juicyway.com/exchange/standing-orders/get-standing-order Retrieve details of a specific standing order by its ID. Endpoint ```json theme={null} GET /exchange/standing-orders/{id} ``` #### **Path Parameters:** * **`id`** (string, required): Standing Order ID. #### **Responses:** * **`200`** - Standing Order Retrieved **Sample:** ```json theme={null} { "data": { "archived": false, "created_at": "2023-12-23T17:55:42.911", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "low_watermark_qty": 1, "min_qty": null, "qty": 3, "strict": false, "symbol": "USD-NGN", "type": "buy", "updated_at": "2023-12-23T17:55:42.911" } } ``` * 404 - Not Found # List Standing Orders Source: https://docs.juicyway.com/exchange/standing-orders/list-standing-orders Retrieve a list of standing orders with pagination support. Endpoint ```json theme={null} GET /exchange/standing-orders ``` # Update Standing Order Source: https://docs.juicyway.com/exchange/standing-orders/update-standing-order Update an existing standing order. Endpoint ```json theme={null} PUT /exchange/standing-orders/{id} ``` #### **Path Parameters:** * **`id`** (string, required): Standing Order ID. #### **Request Body:** **Content Type:** `application/json` **Sample:** ```json theme={null} { "archived": false, "qty": 1, "strict": true } ``` #### **Responses:** * **`201`** - Standing Order Updated**Sample:** ```json theme={null} { "data": { "archived": false, "created_at": "2023-12-23T17:55:42.911", "entity": { "id": "6ebe0a0f-bb8f-49be-80ea-c6b72c348fea", "type": "business" }, "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "low_watermark_qty": 1, "min_qty": null, "qty": 3, "strict": false, "symbol": "USD-NGN", "type": "buy", "updated_at": "2023-12-23T17:55:42.911" } } ``` * 422 - Unprocessable Entity # Create a Swap Configuration Source: https://docs.juicyway.com/exchange/swap-configurations/create-swap-configuration Create a Swap Configuration Endpoint ```json theme={null} POST /exchange/swap-configurations ``` #### **Request Body:** **Content Type:** `application/json` **Sample Request Body:** ```json theme={null} { "symbol": "USD-NGN", "ttl": 10, "type": "buy" } ``` #### **Responses:** * **`201`** - Swap Configuration Created **Sample:** ```json theme={null} { "data": { "id": "string", "order_type": "sell", "symbol": "string", "ttl": 0 } } ``` * 422 - Unprocessable Entity # Delete a Swap Configuration Source: https://docs.juicyway.com/exchange/swap-configurations/delete-swap-configuration Delete a swap configuration by its ID. Endpoint ```json theme={null} DELETE /exchange/swap-configurations/{id} ``` #### **Path Parameters:** * **`id`** (string, required): Swap Configuration ID. #### **Query Parameters:** * **`token`** (string, optional): Token for additional validation. #### **Responses:** * **`204`** - No Content * **`404`** - Not Found # Retrieve Swap Configuration Source: https://docs.juicyway.com/exchange/swap-configurations/get-swap-configuration Retrieve details of a specific swap configuration by its ID. **Endpoint** ```json theme={null} GET /exchange/swap-configurations/{id} ``` #### **Path Parameters:** * **`id`** (string, required): Swap Configuration ID. #### **Responses:** * **`200`** - Swap Configuration Retrieved **Sample:** ```json theme={null} { "data": { "id": "string", "order_type": "sell", "symbol": "string", "ttl": 0 } } ``` * 404 - Not Found # List Swap Configuration Source: https://docs.juicyway.com/exchange/swap-configurations/list-swap-configurations Retrieve a list of swap configurations with pagination support. Endpoint ```json theme={null} GET /exchange/swap-configurations ``` #### **Query Parameters:** * **`before`** (string, optional): Cursor for pagination (before). * **`after`** (string, optional): Cursor for pagination (after). * **`limit`** (integer, optional): Number of records to return. * **`symbol`** (string, optional): Filter by symbol. #### **Responses:** * **`200`** - Swap List**Sample:** ```json theme={null} { "data": [ { "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2021-01-01T00:00:00Z", "customer": { "email": "customer@email.com", "id": "1", "name": "User 1", "type": "user" }, "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "provider": { "email": "provider@email.com", "id": "1", "name": "Provider 1", "type": "provider" }, "source_amount": { "amount": 1, "currency": "USD" }, "status": "success", "symbol": "USD-NGN", "target_amount": { "amount": 1000, "currency": "NGN" }, "updated_at": "2021-01-01T00:00:00Z" } ], "pagination": { "after": "b101f718-d133-450c-a572-c281c7341803", "before": null, "limit": 15 } } ``` # Update Swap Configuration Source: https://docs.juicyway.com/exchange/swap-configurations/update-swap-configuration Update an existing swap configuration. Endpoint ```json theme={null} PUT /exchange/swap-configurations/{id} ``` #### **Path Parameters:** * **`id`** (string, required): Swap Configuration ID. #### **Request Body:** **Content Type:** `application/json` **Sample:** ```json theme={null} { "symbol": "USD-NGN", "ttl": 10, "type": "buy" } ``` **Responses** **`201`** - Swap Configuration Updated **Sample** ```json theme={null} { "data": { "id": "string", "order_type": "sell", "symbol": "string", "ttl": 0 } } ``` **`422`** - Unprocessable Entity # Get Swap Source: https://docs.juicyway.com/exchange/swaps/get-swap Retrieve details of a specific swap by ID. ```json theme={null} GET /exchange/swap/{id} ``` **Parameters:** * `id` (string, required): The unique ID of the swap. **Sample Request** ```bash theme={null} curl -X GET "https://exchange.spendjuice.com/v1/exchange/swap/7da8e726-a1bc-11ee-80cf-560f156a658b" \ -H "Authorization: YOUR_API_KEY" ``` **Sample Response** ```json theme={null} { "data": { "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2021-01-01T00:00:00Z", "customer": { "email": "customer@email.com", "id": "1", "name": "User 1", "type": "user" }, "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "provider": { "email": "provider@email.com", "id": "1", "name": "Provider 1", "type": "provider" }, "source_amount": { "amount": 1.0, "currency": "USD" }, "status": "success", "symbol": "USD-NGN", "target_amount": { "amount": 1000.0, "currency": "NGN" }, "updated_at": "2021-01-01T00:00:00Z" } } ``` # Get Swap Rate Source: https://docs.juicyway.com/exchange/swaps/get-swap-rate Retrieve the current swap rate for a currency pair. ```json theme={null} GET /exchange/quote/{id}} ``` **Parameters:** * `source_currency` (string, required): Source currency (e.g., `USD`). * `target_currency` (string, required): Target currency (e.g., `NGN`). **Sample Request** ```bash theme={null} curl --location 'https://api.spendjuice.com/exchange/quote?source_currency=NGN&target_currency=USD' \ --header 'Authorization: ' ``` **Sample Response** ```json theme={null} { "data": { "id": "2f939fe5-fb7b-4234-8b73-761a848d13af", "locked": true, "rate": 1500, "symbol": "USD-NGN", "time_to_convert": 10, "time_to_lock": 30, "type": "buy" } } ``` **Path Parameter**: * `id` *(string, required)*: The unique identifier of the rate to retrieve. **Example**: `3f27a046-314d-457f-b39b-1ec30561353d` * `.time_to_convert` * **Description**: The Time-To-Live (TTL) of the rate in seconds. * `time_to_lock` * **Description**: The duration (in seconds) before the rate becomes available for locking while it is being unlocked. * `locked` * **Description**: * A locked quote is available for use in a swap within the `time_to_convert` interval. * An unlocked rate will become unavailable after the `time_to_lock` interval. * By default, the quote is locked for authenticated requests. * To prevent locking, add `lock=false` to the quote endpoint parameters. * `type` * **Description**: Specifies the conversion side from the provider's perspective. Possible values are `buy` or `sell`. ## Locking a Rate Once you have fetched a quote, you can use the request below to lock it in. ``` curl --location --request POST 'https://api.spendjuice.com/exchange/quote//lock' \ --header 'Authorization: ' ``` # List Swaps Source: https://docs.juicyway.com/exchange/swaps/list-swaps Retrieve a list of swaps. ```json theme={null} GET /exchange/swap ``` **Parameters:** * `before` (string, optional): Cursor for pagination (before). * `after` (string, optional): Cursor for pagination (after). * `limit` (integer, optional): Limit the number of swaps returned. * `symbol` (string, optional): Filter by currency pair symbol. **Sample Request** ```bash theme={null} curl -X GET "https://exchange.spendjuice.com/v1/exchange/swap?limit=10&symbol=USD-NGN" \ -H "Authorization: YOUR_API_KEY" ``` Sample Response ```json theme={null} { "data": [ { "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2021-01-01T00:00:00Z", "customer": { "email": "customer@email.com", "id": "1", "name": "User 1", "type": "user" }, "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "provider": { "email": "provider@email.com", "id": "1", "name": "Provider 1", "type": "provider" }, "source_amount": { "amount": 1.0, "currency": "USD" }, "status": "success", "symbol": "USD-NGN", "target_amount": { "amount": 1000.0, "currency": "NGN" }, "updated_at": "2021-01-01T00:00:00Z" } ], "pagination": { "after": "b101f718-d133-450c-a572-c281c7341803", "before": null, "limit": 10 } } ``` # Make Swap Source: https://docs.juicyway.com/exchange/swaps/make-swaps Execute a swap between two currencies. ```json theme={null} POST /exchange/swap ``` **Parameters:** * `amount` (integer, required): Amount in minor units. * `source_currency` (string, required): Source currency (e.g., `USD`). * `target_currency` (string, required): Target currency (e.g., `NGN`). **Sample Request** ````bash theme={null} curl --location 'https://api.spendjuice.com/exchange/swap' \ --header 'Authorization: ' --data '{ "amount": 1000, "source_currency": "NGN", "target_currency": "USD", "quote_id": "4bed6a6a-2431-4a51-9600-d0badd939bf7" }' ``` ```` **Sample Response** ```json theme={null} { "data": { "correlation_id": "7da742ea-a1bc-11ee-b907-560f156a658b", "created_at": "2021-01-01T00:00:00Z", "customer": { "email": "customer@email.com", "id": "1", "name": "User 1", "type": "user" }, "id": "7da8e726-a1bc-11ee-80cf-560f156a658b", "provider": { "email": "provider@email.com", "id": "1", "name": "Provider 1", "type": "provider" }, "source_amount": { "amount": 1.0, "currency": "USD" }, "status": "success", "symbol": "USD-NGN", "target_amount": { "amount": 1000.0, "currency": "NGN" }, "updated_at": "2021-01-01T00:00:00Z" } } ``` # Home Source: https://docs.juicyway.com/home Welcome to the Juicyway Developer Documentation. Here, you'll learn how to create incredible payment experiences securely using our API. Juicyway provides a REST API that allows you to seamlessly accept payments from your customers via multiple payment methods such as Debit cards, Bank transfers, Crypto transfers and Interac e-transfers. The API delivers responses in a secure JSON format. ## Getting Started Get up and running with Juice API in minutes. Learn how to make your first API call and process test payments in our sandbox environment. Secure your API requests with proper authentication. Learn about API keys and best practices for securing your integration. Set up real-time notifications for payment events. Receive updates about transactions and system events automatically. Learn about error codes, messages, and best practices for handling errors in your integration. ## Development Environments We provide two distinct environments to cater to your development and deployment needs: ```bash Sandbox theme={null} https://api-sandbox.spendjuice.com ``` ```bash Production theme={null} https://api.spendjuice.com ``` * **Sandbox Environment:** This environment is specifically designed for testing your integration with Juice. It facilitates a risk-free environment where you can experiment without processing real payments . * **Production Environment:** Once you've thoroughly tested your integration within the Sandbox environment, you can transition to the Production environment for processing live transactions. Always test your integration thoroughly in the sandbox environment before moving to production. ## Core Features [**Collect payments**](https://docs.juicyway.com/payments/overview) through multiple channels: * Credit/Debit Cards * Bank Transfers * Crypto Transfers Access powerful currency exchange features to facilitate multi-currency transactions. Seamlessly move funds between accounts using our secure APIs Manage transactions, view analytics, and handle customer support through our intuitive dashboard. ## Next Steps After reviewing this documentation, you can: 1. Follow our [Quick Start Guide](/quickstart) to begin integration 2. Set up [Authentication](/authentication) for secure API access 3. Configure [Webhooks](/webhooks) for real-time updates 4. Review common [Errors](/errors) and how to handle them 5. Test transactions in the sandbox environment 6. Go live with your integration Need help? Contact our support team at [support@juicyway.com](mailto:support@juicyway.com) # Fetch Payment Source: https://docs.juicyway.com/payment-transactions/fetch-payment Retrieve details of a specific payment by ID ## Overview The Fetch Payment endpoint allows you to retrieve detailed information about a specific payment using its unique identifier. This is useful for checking payment status, verifying transaction details, or retrieving customer information associated with the payment. ## Endpoint ```bash theme={null} GET /payments/{id} ``` ## Authentication All requests must include your API key in the Authorization header: ```bash theme={null} Authorization: YOUR_API_KEY ``` ## Path Parameters The unique identifier of the payment to retrieve. * Format: UUID v4 * Example: `2315fca8-9aec-42ee-8bee-a9d10add170e` ## Response Structure The payment details object Unique identifier for the payment Payment amount in minor units (e.g., cents, kobo) Three-letter currency code (e.g., NGN, USD) Current status of the payment. One of: * pending * processing * succeeded * failed * cancelled Details about the customer who made the payment Information about the payment method used ## Examples ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/payments/2315fca8-9aec-42ee-8bee-a9d10add170e" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/payments/2315fca8-9aec-42ee-8bee-a9d10add170e', { headers: { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } } ); const payment = await response.json(); ``` ```python Python theme={null} import requests headers = { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } response = requests.get( 'https://api.spendjuice.com/payments/2315fca8-9aec-42ee-8bee-a9d10add170e', headers=headers ) payment = response.json() ``` ## Response Examples ```json 200 - Successful Response theme={null} { "data": { "amount": 10000, "cancellation_reason": null, "correlation_id": "a3f53cea-e05a-11ee-8a6d-8a7019bc5d83", "currency": "NGN", "customer": { "billing_address": { "city": "Torphy", "country": "NG", "line1": "46259 Brekke Adella Rapids", "line2": "Suite 304", "state": "River", "zip_code": "53292" }, "email": "greg_gleichner@hansen.net", "first_name": "Murray Inc", "id": "53380ca0-b29d-4dd4-8732-8fd518f4a394", "last_name": "", "phone_number": "+2348023321025" }, "date": "2024-03-12T10:23:59.750724Z", "description": "Test", "id": "a3f53772-e05a-11ee-9444-8a7019bc5d83", "order": { "identifier": "Veniam quaerat dolor?", "items": [ { "name": "Small Rubber Shoes", "type": "digital" } ] } "mode": "test", "payment_method": { "account_name": "Carrie Romaguera Sr.", "account_number": "34521736", "account_type": "savings", "bank_name": "Conn Group", "id": "1e140102-3ddc-41d1-aaaf-b101cd195377", "type": "bank_account" }, "reference": "Possimus rerum.", "status": "pending" } } ``` ```json 404 - Payment Not Found theme={null} { "error": { "code": "payment_not_found", "message": "No payment found with ID: 2315fca8-9aec-42ee-8bee-a9d10add170e" } } ``` ```json 401 - Unauthorized theme={null} { "error": { "code": "unauthorized", "message": "Invalid or missing API key" } } ``` ## Error Handling | Status Code | Description | Possible Solution | | ----------- | -------------------------- | ------------------------------------------- | | 401 | Invalid or missing API key | Check your API key and authorization header | | 403 | Permission denied | Verify your API key has correct permissions | | 404 | Payment not found | Verify the payment ID exists and is valid | | 429 | Rate limit exceeded | Implement exponential backoff | | 500 | Internal server error | Contact support | ## Best Practices 1. Implement proper error handling for all status codes 2. Use exponential backoff for retries 3. Log errors with payment IDs for debugging 4. Handle network timeouts appropriately 1. Never log complete payment details 2. Keep API keys secure 3. Use HTTPS for all API calls 4. Validate payment IDs before making requests 1. Cache payment details when appropriate 2. Implement request timeouts 3. Monitor API response times 4. Use connection pooling for multiple requests ## Rate Limits This endpoint is subject to rate limiting: * 100 requests per minute per API key * Rate limit info included in response headers: * X-RateLimit-Limit * X-RateLimit-Remaining * X-RateLimit-Reset For additional assistance: * Review our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # List Payments Source: https://docs.juicyway.com/payment-transactions/list-payments Retrieve a paginated list of payment transactions with filtering and sorting options. ## Overview This endpoint retrieves a list of payment transactions with support for pagination, filtering, and sorting. Results are ordered by creation date in descending order by default. ```bash theme={null} GET /payments ``` ## Query Parameters Filter by payment status. * Available values: `pending`, `captured`, `settled`, `failed` * Example: `status=settled` Cursor for fetching records before a specific position. * Use for backward pagination * Example: `before=pay_123xyz` Cursor for fetching records after a specific position. * Use for forward pagination * Example: `after=pay_456abc` Number of records to return per page (max: 100). * Example: `limit=25` Filter payments created after this timestamp (ISO 8601). * Example: `created_after=2024-01-01T00:00:00Z` Filter payments created before this timestamp (ISO 8601). * Example: `created_before=2024-03-31T23:59:59Z` ## Response Format Array of payment objects. Each payment object contains: Unique payment identifier Payment amount in minor units Three-letter currency code Payment status (`pending`, `captured`, `settled`, `failed`) Customer details including name, email, and billing address Payment method details and type Payment creation timestamp Additional payment order Cursor for the previous page Cursor for the next page Number of records per page ## Examples ### Basic List Request ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/payments?limit=2" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch('https://api.spendjuice.com/payments?limit=2', { headers: { 'Authorization': ' YOUR_API_KEY' } }); ``` ```python Python theme={null} import requests response = requests.get( 'https://api.spendjuice.com/payments', params={'limit': 2}, headers={'Authorization': ' YOUR_API_KEY'} ) ``` ### Response Examples ```json 200 Success theme={null} { "data": [ { "auth_type": "3ds", "expires_at": "2024-03-01T08:43:08.110470Z", "links": {}, "message": "Successful", "payment": { "amount": 50000, "cancellation_reason": null, "correlation_id": "2549dcf4-d743-11ee-9d95-c6d49632367b", "currency": "NGN", "customer": { "billing_address": { "city": "Awolowo Road", "country": "NG", "line1": "Opposite Sasa Estate", "line2": null, "state": "Kwara", "zip_code": "23401" }, "email": "asajuenitan@gmail.com", "first_name": "Enitan", "id": "d05e51df-809e-498a-ac3f-7acfc0b5d35d", "last_name": "Michael", "phone_number": "+2348036120313" }, "date": "2024-02-29T20:43:08.344264Z", "description": "Deposit", "id": "2549c96c-d743-11ee-aa4d-c6d49632367b", "order": { "identifier": "dbf99bd0-262a-46bd-8339-3c741d040dbb", "items": [ { "name": "Deposit", "type": "digital" } ] } "mode": "live", "payment_method": { "card_number": "417396******9621", "expiry_month": 6, "expiry_year": 2024, "id": "5e21efda-c526-4057-92f6-1b94ee210b47", "type": "card" }, "reference": "85d53ab5-92b8-4151-9f8f-a4f12863a911", "status": "settled" }, "status": "settled" } ], "pagination": { "after": "2549c96c-d743-11ee-aa4d-c6d49632367b", "before": null, "limit": 2 } } ``` ```json 400 Bad Request theme={null} { "error": { "code": "invalid_request", "message": "Invalid query parameters", "details": { "limit": ["Must be between 1 and 100"] } } } ``` ## Pagination The API uses cursor-based pagination to handle large collections of payments: 1. Initial request: Specify `limit` (default: 15) 2. Subsequent requests: Use the `after` cursor from the previous response 3. Previous page: Use the `before` cursor if available For optimal performance: * Use reasonable page sizes (15-50 records) * Cache results when possible * Implement progressive loading in your UI ## Filtering Tips ```bash theme={null} # Get all settled payments GET /payments?status=settled # Get failed payments from last 24 hours GET /payments?status=failed&created_after=2024-03-14T00:00:00Z ``` ```bash theme={null} # Get payments for March 2024 GET /payments?created_after=2024-03-01T00:00:00Z&created_before=2024-03-31T23:59:59Z ``` ## Rate Limits This endpoint has the following rate limits: * 1000 requests per hour per API key * Maximum of 100 records per request * Burst limit: 100 requests per minute ## Best Practices 1. **Efficient Filtering** * Use filters to reduce response size * Combine filters for precise results * Cache frequently accessed data 2. **Pagination Handling** * Store cursors temporarily for navigation * Implement infinite scroll for large lists * Show loading states during fetches 3. **Error Handling** * Implement proper retry logic * Handle rate limits gracefully * Log pagination errors For additional assistance: * Review our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Payment Statistics Source: https://docs.juicyway.com/payment-transactions/payment-statistics Retrieve aggregate statistics about your payment transactions ## Overview The Payment Statistics API provides aggregated metrics about your payment transactions across different statuses. This helps you monitor payment flows and track success/failure rates. ```http theme={null} GET /payments/stats ``` ## Authentication All requests must include your API key in the Authorization header: ```bash theme={null} Authorization: YOUR_API_KEY ``` ## Response Fields Payment statistics container object. Number of payments successfully captured but not yet settled Number of failed payment attempts Number of payments currently in progress Number of payments fully completed and settled Total number of payment attempts across all statuses ## Examples ### Basic Statistics Request ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/payments/stats" \ -H "Authorization: YOUR_API_KEY" ``` ```python Python theme={null} import requests response = requests.get( 'https://api.spendjuice.com/payments/stats', headers={'Authorization': ' YOUR_API_KEY'} ) ``` ```javascript Node.js theme={null} const response = await fetch('https://api.spendjuice.com/payments/stats', { headers: { 'Authorization': ' YOUR_API_KEY' } }); ``` ### Success Response ```json 200 Success theme={null} { "data": { "captured": 2, "failed": 5, "pending": 2, "settled": 8, "total": 20 } } ``` ```json Empty Stats theme={null} { "data": { "captured": 0, "failed": 0, "pending": 0, "settled": 0, "total": 0 } } ``` ## Data Aggregation The statistics endpoint aggregates payment data with the following characteristics: * Updates in near real-time as payment statuses change * Includes payments from the last 30 days by default * Counts each payment exactly once based on its current status * Excludes test mode payments from production statistics ## Usage Examples ### Monitor Payment Success Rate ```javascript theme={null} const stats = await getPaymentStats(); const successRate = (stats.data.settled / stats.data.total) * 100; console.log(`Payment Success Rate: ${successRate}%`); ``` ### Track Failed Payments ```javascript theme={null} const stats = await getPaymentStats(); if (stats.data.failed > 0) { notifyTeam(`${stats.data.failed} failed payments require attention`); } ``` ## Best Practices 1. **Caching** * Cache statistics for up to 5 minutes to reduce API load * Implement stale-while-revalidate caching strategy * Clear cache when receiving payment webhooks 2. **Error Handling** * Implement exponential backoff for retries * Handle network timeouts gracefully * Log unusual statistical patterns 3. **Monitoring** * Track success rate trends over time * Set up alerts for unusual failure rates * Monitor pending payment resolution times For questions about payment statistics: * Review our [Error Handling](/errors) guide * Contact [support@juicyway.com](mailto:support@juicyway.com) * Join our [Discord community](https://discord.gg/juice) # Authorize Payment Source: https://docs.juicyway.com/payments/authorize-payment Learn about payment authorization in the Juice API ## Overview Payment authorization is a critical step in the transaction flow where a customer's payment credentials are validated and checked before capturing the payment. The authorization process helps ensure: 1. The payment method is valid and active 2. Sufficient funds are available 3. The transaction is not suspicious or fraudulent ### Authorization Types Depending on the payment method and risk level, one or more authorization steps may be required: * Card number validation * CVV/CVC check * Address verification (AVS) * 3D Secure authentication * Account ownership verification * Balance check * Account status validation * One-time passwords * PIN validation * Security questions Authorization requirements vary by: * Payment method * Transaction amount * Geographic region * Customer risk profile Refer to the specific [payment method guides](/payments/overview) for detailed authorization steps and requirements. # Cards Source: https://docs.juicyway.com/payments/authorize-payment/cards Auth flow for card transactions. ## Authorization During the payment capture process, additional authentication steps may be required due to the specific card involved. These may include OTP validation, PIN validation, or even 3DS (3D Secure). ```http theme={null} POST /payment-sessions/{payment_id}/authorize ``` ```json theme={null} // otp authorize { "otp": "123456" //5 or 6 digit string } // pin authorize { "pin": "1234" //4 digit string } // card_enroll & 3ds { "card_enroll": "" //string } // Cvv { "cvv": "123" //string } ``` **Sample Response** ```json theme={null} { "data": { "url": "", "status": "captured|failed", "message": "", "payment": { "id": , "currency": , "amount": , "description": , "payment_method": { "card_number": "", "expiry_month": , "expiry_year": , "id": "", "type": "card" }, "status": "pending", "date": , "mode": , "customer": { "first_name": , "last_name": , "email": , "billing_address": { "line1": , "line2": , "city": , "state": , "zip_code": , "country": , } }, "reference": , "metadata": {} } } } ``` # Payment Capture Source: https://docs.juicyway.com/payments/capture-payment Payment capture is the binding stage in the transaction lifecycle where funds are transferred from the customer's account to your merchant account. This process occurs after successful authorization and represents the final step in completing a payment. ## Overview Before attempting to capture a payment: * Ensure you have a valid payment session ID * Verify any required authorizations are complete * Check that the payment hasn't expired ## Supported Payment Methods **Features** * Direct capture after authorization * 3DS/OTP support where required * Partial captures supported * Real-time status updates **Features** * Virtual account generation * Multiple bank support * Automated reconciliation * Real-time notifications **Features** * Multi-chain support (ETH, TRX) * USDT/USDC acceptance * Automated rate conversion * Cross-border capability **Features** * Direct wallet integration * Instant settlement * Multiple currencies ## Processing Times * Standard capture: Near instant * 3DS Authentication: 1 - 5 minutes * Refunds: 5 - 7 business days * NGN transfers: 1.5 - 10 minutes * USD/International: 1 - 3 business days * CAD (Interac): 5 - 15 minutes * TRX Network: 1-3 minutes * ETH Network: 5-30 minutes * MATIC Network: 1-5 minutes * Standard capture: Near instant * Confirmation time: 1-2 minutes ## Capture Flow The general payment capture process follows these steps: Check that the payment session is valid and in an authorized state Complete any required authentication steps: * 3D Secure for cards * OTP validation * PIN verification Make the API call to capture the payment with: * Payment session ID * Capture amount (for partial captures) * Any method-specific parameters Handle the capture response: * Success: Update your systems * Pending: Wait for webhook * Failed: Handle error appropriately Track the payment status via: * Webhook notifications (recommended) * Status check endpoints ## Method-Specific Guides For detailed implementation instructions, see the following guides: * [Card Payments](/payments/capture-payment/cards) * [Bank Transfers](/payments/capture-payment/bank-transfer) * [Stablecoins](/payments/capture-payment/stablecoins-payment) * [Binance Pay](/payments/capture-payment/binance-pay) * [Interac e-Transfer](/payments/capture-payment/interac) ## Best Practices * Implement exponential backoff for retries * Handle timeouts gracefully * Log all capture attempts * Monitor failed captures * Set appropriate timeout limits * Validate all capture requests * Use HTTPS for API calls * Follow PCI compliance for card data * Implement proper access controls * Rotate API keys regularly * Track capture success rates * Monitor processing times * Set up alerts for failures * Review capture logs regularly * Record all capture attempts * Match captures to authorizations * Reconcile daily transactions * Track partial captures * Monitor settlement status ## Testing Always test capture flows in our sandbox environment first: * Use test cards for card payments * Test different authentication scenarios * Verify webhook handling * Check error responses ## Rate Limits Capture requests are subject to rate limiting: * 100 requests per minute per API key * Burst limit: 10 requests per second * Monitor rate limit headers in responses For additional support: * Check our [API Reference](/api-reference/overview) * Review the [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Bank Transfer Source: https://docs.juicyway.com/payments/capture-payment/bank-transfer Capture payments via bank transfer with virtual accounts ## Overview Bank transfer capture generates a virtual account where the customer can deposit funds. This is an asynchronous process - you'll receive webhook notifications when the transfer is detected and completed. Virtual accounts are typically valid for 24 hours. Monitor the `expires_at` field in the response to know when the account will expire. ## Capture Flow Call the capture endpoint to get bank account details Customer initiates transfer to provided account System detects incoming transfer Receive webhook notification of successful payment ## Endpoint ```http theme={null} POST /payment-sessions/{payment_id} ``` ### Path Parameters The ID of the payment session to capture ### Request Example ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/payment-sessions/265710b4-255d-11ee-add2-2ae94e9097ac" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/payment-sessions/265710b4-255d-11ee-add2-2ae94e9097ac', { method: 'POST', headers: { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } } ); const result = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.spendjuice.com/payment-sessions/265710b4-255d-11ee-add2-2ae94e9097ac', headers={ 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } ) ``` ### Response Example ```json theme={null} { "data": { "auth_type": null, "expires_at": "2024-03-20T11:56:43.482556Z", "links": {}, "message": "Waiting for payment resolution", "payment": { "amount": 100000, "cancellation_reason": null, "correlation_id": "26571e60-255d-11ee-b2a8-2ae94e9097ac", "currency": "NGN", "customer": { "billing_address": { "city": "Ikeja", "country": "NG", "line1": "1, Church Street", "line2": "235 Hello Drive", "state": "Lagos State", "zip_code": "23401" }, "email": "customer@example.com", "first_name": "John", "last_name": "Doe" }, "date": "2024-03-19T11:20:50.050770Z", "description": "Product Purchase", "id": "265710b4-255d-11ee-add2-2ae94e9097ac", "order": { "identifier": "ORD12345", "items": [ { "name": "Premium Package", "type": "digital" } ] } "mode": "live", "payment_method": { "account_name": "JUICE PAYMENTS", "account_number": "7650266816", "account_type": "savings", "bank_name": "Wema Bank", "id": "498c981d-b549-47c1-bb26-abc798b7f398", "type": "bank_account" }, "reference": "ord_1234567890", "status": "pending" }, "status": "pending" } } ``` ## Processing Times **Average Processing Times** * NGN transfers: 5-15 minutes * CAD transfers: 1-2 business days Times may vary based on: * Bank network status * Time of day * Transaction volume ## Webhook Events Monitor these webhook events for transfer status: Virtual account generated successfully Transfer detected but not yet confirmed Transfer confirmed and credited Transfer failed or expired ## Best Practices 1. **Display Information** * Show account details clearly * Include transfer instructions * Display expiration time * Show expected processing time 2. **Error Handling** * Handle expired accounts * Implement retry logic * Monitor transfer status * Log all webhook events 3. **User Experience** * Provide clear transfer instructions * Display payment status updates * Send email/SMS notifications * Include support contact info For assistance with bank transfers: * Check our [Error Handling Guide](/errors) * Review [Webhook Implementation](/webhooks) * Contact [Support](mailto:support@juicyway.com) # Cards Source: https://docs.juicyway.com/payments/capture-payment/cards # Card Payment Capture This guide explains how to capture an authorized card payment. The capture request processes the actual charge against the customer's card after authentication. ## Overview Before capturing a payment, ensure: 1. You have a valid payment session ID from initialization 2. Any required card data is encrypted following our [encryption guide](/payments/encryption-keys) 3. You can handle authentication flows if needed ## Endpoint ```bash theme={null} POST /payment-sessions/{payment_id} ``` ## Request Parameters Encrypted card payment details Encrypted card number (PAN) Encrypted CVV/CVC Card expiry month (1-12) Card expiry year (current or future) ## Example Request ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/payment-sessions/{payment_id}" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "card": { "card_number": "encrypted_card_number", "cvv": "encrypted_cvv", "expiry_month": 1, "expiry_year": 39 } }' ``` ```javascript Node.js theme={null} const response = await fetch( `https://api.spendjuice.com/payment-sessions/${paymentId}`, { method: 'POST', headers: { 'Authorization': ` ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ card: { card_number: encryptedCardNumber, cvv: encryptedCvv, expiry_month: 1, expiry_year: 39 } }) } ); ``` ## Authentication Flows Some card payments require additional authentication after capture: ### 3D Secure (3DS) ```json theme={null} { "data": { "status": "authenticating", "auth_type": "3ds", "message": "3D Secure authentication required", "links": { "redirect_url": "https://3ds.issuer-bank.com/auth" } } } ``` Redirect customer to provided URL to complete 3DS Monitor webhooks or status endpoint for final result ### One-Time Password (OTP) ```json theme={null} { "data": { "status": "authenticating", "auth_type": "otp", "message": "OTP sent to registered phone number" } } ``` ```bash theme={null} POST /payment-sessions/{payment_id}/authorize { "otp": "123456" } ``` ### PIN Verification ```json theme={null} { "data": { "status": "authenticating", "auth_type": "pin", "message": "Enter card PIN" } } ``` ```bash theme={null} POST /payment-sessions/{payment_id}/authorize { "pin": "1234" } ``` ## Error Handling Card declined by issuing bank * Status code: 402 * Common reasons: * Insufficient funds * Invalid card * Suspicious activity Additional authentication needed * Status code: 401 * Next steps: * Handle 3DS redirect * Collect OTP/PIN * Retry with authentication ## Best Practices 1. **Authentication Flow** * Handle all authentication types (3DS, OTP, PIN) * Provide clear user feedback during auth * Implement proper timeouts and retries * Monitor auth completion via webhooks 2. **Error Handling** * Implement exponential backoff for retries * Show user-friendly error messages * Log errors with payment IDs * Handle timeouts gracefully 3. **Security** * Never log decrypted card data * Use HTTPS for all requests * Clear sensitive data after use * Monitor for unusual patterns * See [Error Handling Guide](/errors) * Review [Authentication](/authentication) * Contact [Support](mailto:support@juicyway.com) # Interac e-Transfer Capture Source: https://docs.juicyway.com/payments/capture-payment/interac Process Interac e-Transfer payments for Canadian transactions ## Overview Capture an Interac e-Transfer payment by generating a secure payment link that your customer can use to complete the transfer. This endpoint supports incoming (receiving) payments through Canada's Interac e-Transfer system. Interac e-Transfer is only available for Canadian dollar (CAD) transactions and requires both the sender and recipient to have Canadian bank accounts. ## Endpoint ```bash theme={null} POST /payment-sessions/{payment_id} ``` ## Capture Flow First create a payment session with [payment initialization](/payments/initialize-payment/interac-e-transfer) Capture the payment to generate an Interac e-Transfer link Customer completes the transfer through their online banking Funds are automatically deposited if enabled, or require security answer ## Response Object ```json theme={null} { "data": { "auth_type": null, "expires_at": "2024-04-09T01:11:30.239705Z", "links": { "redirect_url": "https://gateway-web.fit.interac.ca/reqPayment/eml/CA1MRz75R4Hy" }, "message": "Waiting for payment", "payment": { "amount": 100000, // Amount in cents "currency": "CAD", "status": "pending", "payment_method": { "type": "interac" }, "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+14165555555", "billing_address": { "line1": "123 Main St", "line2": "Unit 4B", "city": "Toronto", "state": "ON", "country": "CA", "zip_code": "M5V 2T6" } }, "description": "Invoice payment", "reference": "inv_20240322_123", "order": { "identifier": "ORD12345", "items": [ { "name": "Professional Services", "type": "service" } ] } } } } ``` ### Important Response Fields Interac e-Transfer payment link to share with customer * Valid for payment session duration * Unique per transaction * Must be accessed within expires\_at time ISO 8601 timestamp when the payment session expires * Default: 1 hours from creation * Customer must complete transfer before this time ## Transaction Limits * Minimum: CAD 100.00 (10000 cents) * Maximum: CAD 10,000.00 (1000000 cents) * Daily Limit: CAD 25,000.00 (2500000 cents) * Monthly Limit: CAD 100,000.00 (10000000 cents) ## Processing Times * Incoming transfers typically process within 15-30 minutes * Auto-deposit reduces processing time * Bank cut-off times may affect processing * Weekend/holiday transfers may take longer ## Error Handling ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid payment session ID" } } ``` ```json theme={null} { "error": { "code": "session_not_found", "message": "Payment session not found" } } ``` ```json theme={null} { "error": { "code": "validation_error", "message": "Invalid currency for Interac e-Transfer" } } ``` ## Best Practices 1. **Customer Communication** * Send the redirect URL immediately to the customer * Include clear transfer instructions * Notify when payment is received 2. **Error Handling** * Implement retry logic for failed captures * Monitor payment session expiration * Handle timeout scenarios properly 3. **Security** * Validate payment sessions before capture * Check transaction limits * Monitor for suspicious patterns 4. **Integration** * Use webhooks for real-time updates * Store payment IDs for reconciliation * Implement proper logging For questions about Interac e-Transfer integration: * See our [API Reference](/api-reference/overview) * Contact [Support](mailto:support@juicyway.com) * Review [Error Handling](/errors) # Stablecoins payment Source: https://docs.juicyway.com/payments/capture-payment/stablecoins-payment # Stablecoin Payment Capture This guide covers how to capture stablecoin payments after initialization. The capture process confirms the blockchain address and network for the payment. ## Overview Ensure you've completed [payment initialization](/payments/initialize-payment/stablecoins-transfer) before attempting capture. ## Endpoint ```bash theme={null} POST /payment-sessions/{payment_id} ``` ## Supported Tokens and Networks **USDC Support Matrix** | Network | Status | Confirmation Time | | ------- | ------ | ----------------- | | ETH | ✅ | 5-30 minutes | | MATIC | ✅ | 1-5 minutes | | AVAXC | ✅ | 1-5 minutes | **USDT Support Matrix** | Network | Status | Confirmation Time | | ------- | ------ | ----------------- | | ETH | ✅ | 5-30 minutes | | TRX | ✅ | 1-3 minutes | Always verify the network matches the token to avoid lost transactions. For example, send USDC only on ETH, MATIC, or AVAXC networks. ## Request Parameters Crypto payment details Blockchain network code: \* ETH (Ethereum) \* TRX (Tron) \* MATIC (Polygon) \* AVAXC (Avalanche C-Chain) Stablecoin type: \* USDC \* USDT ## Example Requests ```json USDT on Tron theme={null} { "crypto_address": { "chain": "TRX", "currency": "USDT" } } ``` ```json USDC on Polygon theme={null} { "crypto_address": { "chain": "MATIC", "currency": "USDC" } } ``` ## Response Format Payment status: "captured", "failed" Additional status information Unique payment identifier Generated blockchain address for payment Selected blockchain network Selected stablecoin Will be "crypto\_address" Current payment status ## Example Response ```json theme={null} { "data": { "status": "captured", "message": "Payment address generated successfully", "payment": { "id": "pay_123abc456def", "currency": "USDT", "amount": 100000, "description": "Crypto payment", "payment_method": { "address": "TAd3A1MPNb3xhWrCpmi9x7UdqtwigWcdea", "chain": "TRX", "currency": "USDT", "id": "f1ce6d0f-b30b-4c53-810d-77584f2a36fb", "type": "crypto_address" }, "status": "captured", "date": "2024-03-15T12:00:00Z", "mode": "live", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "billing_address": { "line1": "123 Main St", "line2": "Apt 4B", "city": "New York", "state": "NY", "zip_code": "10001", "country": "US" } }, "reference": "crypto_pay_123" } } } ``` ## Transaction Flow Capture request generates a unique blockchain address Listen for webhook events: \* crypto.payment.pending - Transaction detected \* crypto.payment.confirmed - Required confirmations reached \* crypto.payment.completed - Funds credited Ensure received amount matches expected payment ## Best Practices * Use TRX network for lowest fees \* Consider ETH during low gas periods \* Use MATIC/AVAXC for faster confirmations * Validate chain/token compatibility \* Handle network congestion gracefully * Monitor transaction timeouts * Display QR code for address \* Show clear network requirements \* Provide transaction instructions * Check our [Error Handling Guide](/errors) \* Contact [support@juicyway.com](mailto:support@juicyway.com) \* Join our [Discord community](https://discord.gg/juice) # Encryption Keys Source: https://docs.juicyway.com/payments/encryption-keys Secure your card data with strong encryption # Payment Data Encryption Never send raw card data directly to your backend or our API. All sensitive payment information must be encrypted client-side before transmission. Protecting customer payment information is critical. Our API uses strong encryption to safeguard sensitive data. This guide explains how to securely handle encryption for card data in your integration. ## Fetching Encryption Keys To encrypt sensitive card information, you first need to retrieve your unique encryption keys. Make a GET request to: ```bash theme={null} GET /keys/encryption-key ``` **Parameters** Environment Mode. Available Values: `live`, `test` **Successful Response (200 OK):** ```json theme={null} { "data": { "encryption_key": "67634cc972d2433b8725c8f6fbfdf792" } } ``` **Error Response (400 Bad Request):** Indicates an issue with the request, such as an invalid `mode`. ### Encryption Process When handling sensitive card data, follow these steps: 1. Fetch the encryption key for your environment (test/live) 2. Format the card data as a JSON string 3. Generate a random initialization vector (IV) 4. Encrypt the data using AES-256-GCM with your encryption key and IV 5. Concatenate the hex-encoded IV, ciphertext, and authentication tag 6. Send the encrypted data to our API Never send raw card data directly to your backend or our API. Always encrypt it first on the client-side. ### Code Examples ```php theme={null} function card_encrypt($payload, $key) { $iv = openssl_random_pseudo_bytes(16); $cipher_text = openssl_encrypt( $payload, "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag ); return implode(':', [ bin2hex($iv), bin2hex($cipher_text), bin2hex($tag) ]); } // Example usage $card_data = json_encode([ 'card_number' => '4111111111111111', 'expiry_month' => '12', 'expiry_year' => '2025', 'cvv' => '123' ]); $encrypted = card_encrypt($card_data, $encryption_key); ``` ```javascript theme={null} const cardEncrypt = async (payload, encKey) => { const _iv = crypto.getRandomValues(new Uint8Array(12)); const encodedPlaintext = new TextEncoder().encode(payload); const secretKey = await crypto.subtle.importKey( "raw", Buffer.from(encKey, "utf8"), { name: "AES-GCM", length: 256, }, true, ["encrypt", "decrypt"], ); const cipherText = await crypto.subtle.encrypt( { name: "AES-GCM", iv: _iv, }, secretKey, encodedPlaintext, ); const [value, auth_tag] = [ cipherText.slice(0, cipherText.byteLength - 16), cipherText.slice(cipherText.byteLength - 16), ]; const cipher = Buffer.from(value).toString("hex"); const iv = Buffer.from(_iv).toString("hex"); const tag = Buffer.from(auth_tag).toString("hex"); return [iv, cipher, tag].join(":"); }; // Example usage const cardData = JSON.stringify({ card_number: '4111111111111111', expiry_month: '12', expiry_year: '2025', cvv: '123' }); const encrypted = await cardEncrypt(cardData, encryptionKey); ``` ```python theme={null} from cryptography.hazmat.primitives.ciphers.aead import AESGCM import os import json import binascii def card_encrypt(payload, key): # Convert hex key to bytes key_bytes = bytes.fromhex(key) # Generate random IV iv = os.urandom(12) # Create AESGCM instance aesgcm = AESGCM(key_bytes) # Encrypt the payload payload_bytes = payload.encode() cipher_text = aesgcm.encrypt(iv, payload_bytes, None) # Split cipher text and auth tag auth_tag = cipher_text[-16:] encrypted_data = cipher_text[:-16] # Format result return ':'.join([ binascii.hexlify(iv).decode(), binascii.hexlify(encrypted_data).decode(), binascii.hexlify(auth_tag).decode() ]) # Example usage card_data = json.dumps({ 'card_number': '4111111111111111', 'expiry_month': '12', 'expiry_year': '2025', 'cvv': '123' }) encrypted = card_encrypt(card_data, encryption_key) ``` ```ruby theme={null} require 'openssl' require 'json' def card_encrypt(payload, key) # Convert hex key to binary key_bin = [key].pack('H*') # Generate random IV iv = OpenSSL::Random.random_bytes(12) # Create cipher cipher = OpenSSL::Cipher.new('aes-256-gcm') cipher.encrypt cipher.key = key_bin cipher.iv = iv # Encrypt cipher.auth_data = "" encrypted = cipher.update(payload) + cipher.final tag = cipher.auth_tag # Format result [ iv.unpack('H*')[0], encrypted.unpack('H*')[0], tag.unpack('H*')[0] ].join(':') end # Example usage card_data = JSON.generate({ card_number: '4111111111111111', expiry_month: '12', expiry_year: '2025', cvv: '123' }) encrypted = card_encrypt(card_data, encryption_key) ``` ### Security Best Practices * Store encryption keys securely in environment variables or a key management service * Never commit encryption keys to source control * Rotate encryption keys periodically (we'll notify you before key expiration) * Use different keys for test and production environments * Encrypt sensitive data as soon as it's collected * Clear sensitive data from memory after use * Never log or store raw card data * Use HTTPS for all API communications * Implement Content Security Policy (CSP) headers * Use Subresource Integrity for external scripts * Minimize the time sensitive data remains in memory * Clear form fields after encryption ### Troubleshooting Guide If you receive an "Invalid encryption format" error: * Verify the encryption key is correct and valid * Ensure IV, ciphertext, and tag are properly concatenated with colons * Check that all components are properly hex-encoded If you receive an "Authentication failed" error: * Verify you're using the correct encryption key for your environment * Check that the authentication tag is being properly generated and included * Ensure the payload hasn't been modified after encryption * **Random IV Generation**: Ensure a new random IV is generated for each encryption * **Memory Management**: Clear sensitive data from variables after use * **Encoding Issues**: Verify proper encoding/decoding of binary data to hex * **Library Version Compatibility**: Check cryptographic library versions match requirements # Payment Initialization Source: https://docs.juicyway.com/payments/initialize-payment Payment initialization is the first step in processing any payment through the Juice API. This guide covers the core concepts, supported payment methods, and common parameters required for initializing payments. ## Overview Before capturing a payment, you must first initialize a payment session with customer and transaction details. The initialization process: 1. Validates the payment request 2. Creates a session identifier 3. Sets up the appropriate payment flow 4. Returns payment session details ## Supported Payment Methods Credit and Debit cards\[Visa & Mastercard] Direct bank transfers. * NGN bank accounts. * International wires. * ACH transfers. Cryptocurrency Stablecoins * Direct Binance integration. * Multiple currencies. * Instant settlement. Canadian bank transfers via Interac. * Email money transfer. * Instant deposits. **Coming soon!** * Multiple providers. * Regional support. ## Universal Parameters These parameters are required for all payment initializations regardless of the payment method: Payment amount in minor units (e.g., cents, kobo) * Minimum: 100 * Must be positive integer * Example: 10000 = \$100.00 USD ISO currency code * Supported: NGN, USD, CAD, USDT, USDC * Must match payment method * Example: "USD" Customer information object Valid email address Customer's first name Customer's last name Phone number in E.164 format Billing address details Must be of type `business` or `individual` Customer's ip address * Must be ipv4 e.g 127.0.0.1 Payment description * Maximum length: 200 characters * Will appear on statements Unique transaction reference * Must be unique per transaction * Maximum length: 50 characters Payment method details * Must be of type: "" Order information object Unique identifier type must be one of digital,physical Optional additional data * Nested objects allowed ## Required Headers | Header | Description | Example | | ------------- | -------------------- | ------------------ | | Authorization | Your API key | `skabc123...` | | Content-Type | Request content type | `application/json` | Never expose your API key in client-side code. Always make API calls from your server. ## Basic Flow Create payment session with customer and transaction details Complete any required authentication steps (3DS, OTP, etc.) Finalize the payment after successful authentication Process success/failure and update your system ## Method-Specific Guides For detailed implementation steps for each payment method, see: * [Card Payments](/payments/initialize-payment/cards) * [Bank Transfers](/payments/initialize-payment/bank-transfers) * [Stablecoins](/payments/initialize-payment/stablecoins-transfer) * [Binance Pay](/payments/initialize-payment/binance-pay) * [Interac e-Transfer](/payments/initialize-payment/interac-e-transfer) - See our [API Reference](/api-reference/overview) - Contact [support@juicyway.com](mailto:support@juicyway.com) # Bank Transfer Initialization Source: https://docs.juicyway.com/payments/initialize-payment/bank-transfers Accept bank transfer payments through virtual accounts for various currencies and banking systems. This guide covers the initialization process for bank transfer payments. ## Overview Bank transfers are asynchronous - after initialization, you'll receive a virtual account where the customer can deposit funds. Webhook notifications will inform you of the transfer status. ### Supported Bank Transfer Types * All major Nigerian banks * Instant virtual account generation * Real-time transfer notifications * Processing time: 1.5 - 10 minutes ## Initialize Transfer Payment ```bash theme={null} POST /payment-sessions ``` ### Request Parameters Payment amount in minor units (e.g., cents, kobo) * Minimum: 100 * Must be positive integer * Example: 10000 = \$100.00 USD ISO currency code * Supported: NGN, USD, CAD, USDT, USDC * Must match payment method * Example: "USD" Customer information object Valid email address Customer's first name Customer's last name Phone number in E.164 format Billing address details Must be of type `business` or `individual` Customer's ip address * Must be ipv4 e.g 127.0.0.1 Payment description * Maximum length: 200 characters * Will appear on statements Unique transaction reference * Must be unique per transaction * Maximum length: 50 characters Payment method details * Must be of type: "" Order information object Unique identifier type must be one of digital,physical Optional additional data * Nested objects allowed ### Example Request ```bash curl theme={null} curl -X POST "https://api.spendjuice.com/payment-sessions" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348000000000", "billing_address": { "line1": "123 Main St", "line2": "Suite 456", "city": "Ikoyi", "state": "LA", "country": "NG", "zip_code": "12345" }, "ip_address": "127.0.0.1" }, "description": "Order Payment", "currency": "NGN", "amount": 100000, "direction": "incoming", "payment_method": { "type": "bank_account" }, "reference": "ord_xyz_123", "order": { "identifier": "ORD12345", "items": [ { "name": "Product A", "type": "digital" } ] } }' ``` ```python Python theme={null} import requests url = "https://api.spendjuice.com/payment-sessions" headers = { "Authorization": " YOUR_API_KEY", "Content-Type": "application/json" } data = { "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348000000000", "billing_address": { "line1": "123 Main St", "line2": "Suite 456", "city": "Ikoyi", "state": "LA", "country": "NG", "zip_code": "12345" }, "ip_address": "127.0.0.1" }, "description": "Order Payment", "currency": "NGN", "amount": 100000, "direction": "incoming", "payment_method": { "type": "bank_account" }, "reference": "ord_xyz_123", "order": { "identifier": "ORD12345", "items": [ { "name": "Product A", "type": "digital" } ] } } response = requests.post(url, json=data, headers=headers) print(response.json()) ``` ### Success Response ```json theme={null} { "data": { "auth_type": null, "expires_at": "2024-03-01T08:43:08.110470Z", "links": {}, "message": "Virtual account generated successfully", "payment": { "amount": 100000, "cancellation_reason": null, "correlation_id": "2549dcf4-d743-11ee-9d95-c6d49632367b", "currency": "NGN", "customer": { "billing_address": { "city": "Ikoyi", "country": "NG", "line1": "123 Main St", "line2": "Suite 456", "state": "LA", "zip_code": "12345" }, "email": "john.doe@example.com", "first_name": "John", "id": "d05e51df-809e-498a-ac3f-7acfc0b5d35d", "last_name": "Doe", "phone_number": "+2348000000000" }, "date": "2024-02-29T20:43:08.344264Z", "description": "Order Payment", "id": "2549c96c-d743-11ee-aa4d-c6d49632367b", "order": { "identifier": "ORD12345", "items": [ { "name": "Product A", "type": "digital" } ] } "mode": "live", "payment_method": { "account_name": "JUICE PAYMENTS", "account_number": "1234567890", "bank_name": "Test Bank", "id": "5e21efda-c526-4057-92f6-1b94ee210b47", "type": "bank_account" }, "reference": "ord_xyz_123", "status": "pending" }, "status": "pending" } } ``` ## Transfer Limits Transaction Limits may vary based on * Account verification level. * Transaction history. ## * Minimum: ₦100 * Maximum per transaction: ₦5,000,000 ## Processing Times Transfer processing times vary by: * Bank type (local vs international) * Time of day * Transaction volume * Bank system availability | Currency | Transfer Type | Typical Processing Time | | -------- | ------------- | ----------------------- | | NGN | Local | 1.5 - 10 minutes | ## Error Handling ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid parameters provided", "details": { "amount": ["Amount must be at least 100"] } } } ``` ```json theme={null} { "error": { "code": "validation_error", "message": "The request contains invalid parameters", "details": { "currency": ["Currency must be one of: NGN, USD"] } } } ``` ## Best Practices 1. **Unique References** * Use unique, idempotent references for each transfer * Include your internal order ID in the reference * Store the payment ID returned in the response 2. **Webhook Integration** * Implement webhook handling for transfer status updates * Process webhooks asynchronously * Verify webhook signatures 3. **Error Handling** * Implement proper retry logic * Handle timeouts gracefully * Log all errors with payment references 4. **Customer Communication** * Display virtual account details clearly * Show transfer instructions * Set clear expiration times * Review the [Error Handling Guide](/errors) * Check our [API Reference](/api-reference/overview) * Contact [Support](mailto:support@juicyway.com) # Card Payment Initialization Source: https://docs.juicyway.com/payments/initialize-payment/cards Learn how to initialize card payments securely via the Juicyway API ## Overview Card payment initialization is the first step in processing a card payment. This endpoint creates a payment session that can be used to securely process credit and debit card transactions. ## Endpoint ```bash theme={null} POST /payment-sessions ``` ## Request Parameters Payment amount in minor units (e.g., cents, kobo) * Minimum: 100 * Must be positive integer * Example: 10000 = \$100.00 USD ISO currency code * Supported: NGN, USD, CAD, USDT, USDC * Must match payment method * Example: "USD" Customer information object Valid email address Customer's first name Customer's last name Phone number in E.164 format Billing address details Must be of type `business` or `individual` Customer's ip address * Must be ipv4 e.g 127.0.0.1 Payment description * Maximum length: 200 characters * Will appear on statements Unique transaction reference * Must be unique per transaction * Maximum length: 50 characters Payment method details * Must be of type: "" Order information object Unique identifier type must be one of digital,physical Optional additional data * Nested objects allowed ## Example Requests ```json Basic Card Payment theme={null} { "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348118873422", "billing_address": { "line1": "123 Main St", "line2": "Suite 456", "city": "Springfield", "state": "CA", "country": "US", "zip_code": "12345" }, "ip_address": "127.0.0.1" }, "description": "Premium Package Purchase", "currency": "USD", "amount": 100000, "payment_method": { "type": "card" }, "reference": "ord_1234567890", "order": { "identifier": "ORD12345", "items": [ { "name": "Premium Package", "type": "digital" } ] } } ``` ```json International Card Payment theme={null} { "customer": { "first_name": "Jane", "last_name": "Smith", "email": "jane.smith@example.com", "phone_number": "+2348012345678", "billing_address": { "line1": "10 Victoria Island", "city": "Lagos", "state": "Lagos", "country": "NG", "zip_code": "23401" }, "ip_address": "127.0.0.1" }, "description": "International Purchase", "currency": "NGN", "amount": 500000, "payment_method": { "type": "card" }, "reference": "ord_intl_12345", "order": { "identifier": "INTL12345", "items": [ { "name": "International Package", "type": "digital" } ] }, } ``` ## Test Cards Use these test cards in your sandbox environment to simulate different payment scenarios: **VISA Test Card (NGN)** * Card Number: 4012000033330026 * Expiry Date: 01/39 * CVV: 100 **Mastercard Test Card (USD)** * Card Number: 5123450000000008 * Expiry Date: 12/25 * CVV: 100 **VISA 3DS Test Card** * Card Number: 4761530000000008 * Expiry Date: 05/25 * CVV: 100 * Test OTP: 123456 **Mastercard 3DS Test Card** * Card Number: 5200000000001005 * Expiry Date: 12/25 * CVV: 100 * Test OTP: 123456 **Insufficient Funds** * Card Number: 4000000000000010 * Expiry Date: 01/25 * CVV: 100 **Declined Card** * Card Number: 4000000000000002 * Expiry Date: 01/25 * CVV: 100 ## Response Examples ```json 201 Success - Payment Session Created theme={null} { "data": { "auth_type": "3ds", "expires_at": "2024-03-01T08:43:08.110470Z", "links": {}, "message": "Created", "payment": { "amount": 100000, "cancellation_reason": null, "currency": "USD", "customer": { "billing_address": { "city": "Springfield", "country": "US", "line1": "123 Main St", "line2": "Suite 456", "state": "CA", "zip_code": "12345" }, "email": "john.doe@example.com", "first_name": "John", "id": "cust_1234567890", "last_name": "Doe", "phone_number": "+2348118873422" }, "date": "2024-02-29T20:43:08.344264Z", "description": "Premium Package Purchase", "id": "pay_1234567890", "order": { "identifier": "ORD12345", "items": [ { "name": "Premium Package", "type": "digital" } ] } "mode": "live", "payment_method": { "type": "card" }, "reference": "ord_1234567890", "status": "pending" }, "status": "pending" } } ``` ```json 400 Invalid Request theme={null} { "error": { "code": "invalid_request", "message": "The request was invalid", "details": { "amount": ["Amount must be at least 100000"] } } } ``` ```json 422 Validation Error theme={null} { "error": { "code": "validation_error", "message": "The request contains invalid parameters", "details": { "currency": ["Currency must be one of: NGN, USD, CAD"] } } } ``` ## Authentication Flows Some card payments may require additional authentication steps. The response will indicate the required authentication type: If 3DS is required, you'll receive: ```json theme={null} { "data": { "auth_type": "3ds", "message": "3DS authentication required", "links": { "redirect_url": "https://3ds.payment-processor.com/auth" } } } ``` Redirect the customer to complete 3DS verification, then: 1. Listen for webhook notification, or 2. Poll payment status endpoint For OTP authentication: ```json theme={null} { "data": { "auth_type": "otp", "message": "Please enter OTP to complete transaction" } } ``` Submit OTP via: ```bash theme={null} POST /payment-sessions/{payment_id}/authorize { "otp": "123456" } ``` For PIN authentication: ```json theme={null} { "data": { "auth_type": "pin", "message": "Please enter card PIN" } } ``` Submit PIN via: ```bash theme={null} POST /payment-sessions/{payment_id}/authorize { "pin": "1234" } ``` ## Security Requirements * All card data must be encrypted before transmission * Use our [encryption guide](/payments/encryption-keys) for implementation * Never log or store raw card details * Use our secure payment fields when collecting card data * Follow PCI DSS requirements if handling card data * Implement proper data sanitization * Use HTTPS for all API calls * Include proper authorization headers * Rotate API keys regularly ## Error Handling Card declined by issuing bank * Status code: 402 * Possible reasons: * Insufficient funds * Suspicious activity * Expired card Invalid card details provided * Status code: 400 * Check: * Card number * Expiry date * CVV Failed authentication (3DS/OTP/PIN) * Status code: 401 * Verify credentials and retry Common error scenarios to handle: * Invalid currency code * Amount below minimum * Missing customer information * Invalid phone/email format * Incorrect billing address * Network timeouts ## Next Steps After successful initialization: 1. Handle any required authentication 2. [Capture the payment](/payments/capture-payment/cards) 3. Listen for [webhook notifications](/webhooks) * Review [Authentication Guide](/authentication) * Check [Error Handling](/errors) * Contact [Support](mailto:support@juicyway.com) # Interac e-Transfer Source: https://docs.juicyway.com/payments/initialize-payment/interac-e-transfer Initialize Interac e-Transfer payments for Canadian transactions ## Overview Interac e-Transfer enables secure money transfers between Canadian bank accounts. This endpoint supports both incoming (receiving) and outgoing (sending) transfers. ## Endpoint ```bash theme={null} POST /payment-sessions ``` ## Common Requirements **Canadian-Specific Validation:** * Valid Canadian phone number (+1 format) * Canadian postal code format * Province/territory codes (e.g., ON, BC, AB) * Canadian bank account required ## **Incoming Payments (CAD via Interac Auto-Deposit)**  CAD direct deposits via **Interac Auto-Deposit** streamline the payment process, ensuring that incoming funds are quickly and securely credited to your account, enhancing both convenience and financial management. Auto-deposit is enabled using the **merchant’s registered email**. Once we receive the merchant’s registered email, we configure it for Interac Auto-Deposit. Test incoming CAD deposits in **Production**, as deposits are real-time. ### **Confirming Deposits** To confirm incoming deposits, listen for webhooks. **Example webhook payload (successful CAD deposit):** ```json theme={null} {   "checksum": "",   "data": {     "amount": 10000,     "callback_urls": {},     "cancellation_reason": null,     "channel_reference": "",     "collection_mode": null,     "correlation_id": "",     "currency": "NGN",     "customer": {       "account_id": "",       "billing_address": {         "city": "",         "country": "NG",         "line1": "",         "state": "",         "zip_code": ""       },       "email": "",       "first_name": "",       "id": "",       "last_name": "",       "phone_number": "",       "type": ""     },     "date": "",     "description": "",     "fee": null,     "id": "",     "merchant": {       "address": {         "city": "",         "country": "NG",         "line1": "",         "line2": null,         "state": "",         "zip_code": ""       },       "email": "",       "id": "",       "mcc": "",       "name": "",       "phone": ""     },     "order": {       "identifier": "",       "items": [         {           "name": "Transfer",           "type": "digital"         }       ]     }     "mode": "live",     "order": {       "identifier": "",       "items": [         {           "name": "Transfer",           "type": "digital"         }       ]     },     "payer": {       "account_name": null,       "account_number": null,       "bank_name": ""     },     "payment_method": {       "account_numner": "",       "account_name": "",       "bank_code": "",       "bank_name": "",       "currency": "",       "id": "",       "type": "bank_account"     },     "provider_id": "",     "redirect_url": null,     "reference": "",     "status": "success|failed",     "transaction_id": "",     "type": "payin|payout"   },   "event": "payment.session.succeeded|payment.session.failed" } ``` **Developer tasks:** * Provide the merchant’s **registered email** so it can be enabled for auto-deposit. * Implement an endpoint on your server to receive POST requests from Juicyway. * Verify the checksum for authenticity. * Use status (success) + type (payin) to confirm the CAD deposit. * Update your internal systems (balances, invoices, etc.). ## Overview Capture an Interac e-Transfer payment by generating a secure payment link that your customer can use to complete the transfer. This endpoint supports incoming (receiving) payments through Canada's Interac e-Transfer system. Interac e-Transfer is only available for Canadian dollar (CAD) transactions and requires both the sender and recipient to have Canadian bank accounts. ## Endpoint ```bash theme={null} POST /payment-sessions/{payment_id} ``` ## Capture Flow First create a payment session with [payment initialization](/payments/initialize-payment/interac-e-transfer) Capture the payment to generate an Interac e-Transfer link Customer completes the transfer through their online banking Funds are automatically deposited if enabled, or require security answer ## Response Object ```json theme={null} { "data": { "auth_type": null, "expires_at": "2024-04-09T01:11:30.239705Z", "links": { "redirect_url": "https://gateway-web.fit.interac.ca/reqPayment/eml/CA1MRz75R4Hy" }, "message": "Waiting for payment", "payment": { "amount": 100000, // Amount in cents "currency": "CAD", "status": "pending", "payment_method": { "type": "interac" }, "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+14165555555", "billing_address": { "line1": "123 Main St", "line2": "Unit 4B", "city": "Toronto", "state": "ON", "country": "CA", "zip_code": "M5V 2T6" } }, "description": "Invoice payment", "reference": "inv_20240322_123", "order": { "identifier": "ORD12345", "items": [ { "name": "Professional Services", "type": "service" } ] } } } } ``` ### Important Response Fields Interac e-Transfer payment link to share with customer * Valid for payment session duration * Unique per transaction * Must be accessed within expires\_at time ISO 8601 timestamp when the payment session expires * Default: 1 hours from creation * Customer must complete transfer before this time ## ## ## Outgoing Transfers Use this flow when sending payments to recipients through Interac e-Transfer. ### Additional Parameters for Outgoing Transfers One of: "personal", "business" Recipient's first name Recipient's last name Recipient's Interac-registered email Recipient's phone number (optional) Security question for the transfer Answer to the security question ### Example Request (Outgoing) ```json theme={null} { "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+14165555555", "billing_address": { "line1": "123 Main St", "line2": "Unit 4B", "city": "Toronto", "state": "ON", "country": "CA", "zip_code": "M5V 2T6" }, "ip_address": "127.0.0.1" }, "description": "Expense reimbursement", "currency": "CAD", "amount": 100000, "direction": "outgoing", "payment_method": { "type": "interac", "beneficiary_type": "personal", "first_name": "Jane", "last_name": "Smith", "email": "jane.smith@example.com", "phone_number": "+14165556666", "question": "What is our project code", "answer": "ALPHA123" }, "reference": "exp_20240322_456", "order": { "identifier": "EXP12345", "items": [ { "name": "Travel Reimbursement", "type": "expense" } ] }, } ``` ## ## **Linking Multiple Emails** In situations where a user has multiple email addresses, we typically advise applying restrictions. However, when necessary, you can link a secondary email (Email 2) to the primary registered email (Email 1) using the endpoint below. **Endpoint:** ```bash theme={null} PATCH /customers/:id/register_emails ``` **Request Body:** ```json theme={null} {   "emails": [     "user1@example.com",   // primary registered email (Email 1)     "user2@example.com"    // additional linked email (Email 2)   ] } ``` Validation Rules * Minimum: CAD 100.00 (10000 cents) * Maximum: CAD 10,000.00 (1000000 cents) * Must be in Canadian Dollars (CAD) * Must be a positive integer in cents * Must begin with +1 * Must be 11 digits total (+1 plus 10-digit number) * Area code must be valid for Canada * Must follow Canadian format: "A1A 1A1" * Letter-number-letter number-letter-number * First letter cannot be D, F, I, O, Q, U, W, Z * Required for outgoing transfers * Question must be 10-100 characters * Answer must be 3-50 characters * Cannot contain sensitive information ## Error Handling Invalid Canadian province/territory code provided. * Must be one of: AB, BC, MB, NB, NL, NS, NT, NU, ON, PE, QC, SK, YT Invalid Canadian postal code format. * Must match pattern: A1A 1A1 Invalid Canadian phone number. * Must start with +1 * Must be a valid area code Transfer amount exceeds limits. * Check minimum/maximum allowed amounts ## Processing Times * Incoming transfers: Usually processed within 15-30 minutes * Outgoing transfers: Usually processed within 30-60 minutes * Cutoff times may apply based on recipient's bank For support with Interac e-Transfer integration: * Check our [Error Handling Guide](/errors) * Contact [Support](mailto:support@juicyway.com) # Stablecoin Transfer Source: https://docs.juicyway.com/payments/initialize-payment/stablecoins-transfer Initialize stablecoin payments with support for multiple tokens and chains ## Overview Initialize stablecoin payments using supported tokens across multiple blockchain networks. This endpoint supports both inbound and outbound crypto transactions with real-time rate conversion. ## Supported Tokens and Chains **USDT** * Tron (TRX) **USDC** * Ethereum (ETH) * Polygon (MATIC) * Avalanche C-Chain (AVAXC) Ensure you use the correct chain for each token to avoid lost transactions. Not all tokens are supported on all chains. ## Transaction Limits * Minimum: 18 USDT/USDC * Maximum: 50,000 USDT/USDC per transaction **Transaction limits may vary based on:** * Account verification level * Transaction history * Selected chain/token ## Processing Times * Average: 1-3 minutes * Network fee: Low (\<\$2) * Block confirmations required: 6 * Average: 5-30 minutes * Network fee: Variable (gas fees) * Block confirmations required: 12 * Average: 1-5 minutes * Network fee: Low (\<\$2) * Block confirmations required: 15 ## Initialize Payment ```http theme={null} POST /payment-sessions ``` ### Request Parameters Payment amount in minor units (e.g., cents, kobo) * Minimum: 100 * Must be positive integer * Example: 10000 = \$100.00 USD ISO currency code * Supported: NGN, USD, CAD, USDT, USDC * Must match payment method * Example: "USD" Customer information object Valid email address Customer's first name Customer's last name Phone number in E.164 format Billing address details Must be of type `business` or `individual` Customer's ip address * Must be ipv4 e.g 127.0.0.1 Payment description * Maximum length: 200 characters * Will appear on statements Unique transaction reference * Must be unique per transaction * Maximum length: 50 characters Payment method details * Must be of type: "" Order information object Unique identifier type must be one of digital,physical Optional additional data * Nested objects allowed ### Request Example ```json theme={null} { "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348118873422", "billing_address": { "line1": "123 Main St", "line2": "234 Feranmi Drive", "city": "Springfield", "state": "CA", "country": "US", "zip_code": "12345" }, "ip_address": "127.0.0.1" }, "description": "Crypto Payment", "currency": "USD", "amount": 100000, "direction": "incoming", "payment_method": { "type": "crypto_address" }, "reference": "crypto-tx-123", "order": { "identifier": "ORD12345", "items": [ { "name": "Digital Product", "type": "digital" } ] } } ``` ### Response Example ```json theme={null} { "data": { "status": "pending", "message": "Payment session initialized", "payment": { "id": "pay_123abc456def", "currency": "USD", "amount": 100000, "description": "Crypto Payment", "payment_method": { "address": "TRWBqiqoFZysoAeyR1J35ibuyc8EvhUAoY", "chain": "TRX", "currency": "USDT", "type": "crypto_address" }, "status": "pending", "date": "2024-03-15T12:00:00Z", "mode": "live", "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "billing_address": { "line1": "123 Main St", "line2": "234 Feranmi Drive", "city": "Springfield", "state": "CA", "zip_code": "12345", "country": "US" } }, "reference": "crypto-tx-123", "order": { "identifier": "ORD12345", "items": [ { "name": "Digital Product", "type": "digital" } ] } } } } ``` ## Validation Rules * Must be within min/max limits * Must be in minor units (cents) * Must be a positive integer * Must match chain format * Must be active/valid address * Must support token type * Token must be supported on chain * Chain must be active/operational * Network fees must be reasonable ## Rate Conversion * Exchange rates are locked for 15 minutes * Rates include network fees * Rate source: aggregated from major exchanges * Rate updates: every 30 seconds ## Webhooks Monitor transaction status via webhooks: * `crypto.payment.pending`- Payment detected but unconfirmed * `crypto.payment.confirmed`- Required confirmations reached * `crypto.payment.completed`- Funds credited to account * `crypto.payment.failed`- Transaction failed or expired ## Best Practices 1. **Security** * Validate addresses before displaying * Show clear network/token warnings * Include QR codes for addresses 2. **User Experience** * Display real-time rate updates * Show confirmation progress * Provide clear payment instructions 3. **Error Handling** * Handle network congestion * Implement payment expiry * Monitor transaction status For additional assistance: * Check our [Error Handling](/errors) guide * Contact [Support](mailto:support@juicyway.com) * Join our [Discord](https://discord.gg/juice) # Overview Source: https://docs.juicyway.com/payments/overview Accept payments globally with multiple payment methods and currencies ## Introduction Juicyway's payment system enables businesses to accept payments seamlessly from customers worldwide using various payment methods. Our flexible platform supports both incoming and outgoing transactions, making it ideal for diverse business needs from e-commerce to cross-border payments. ## Payment Directions Accept payments from customers through multiple channels: * E-commerce transactions * Service payments * Digital product purchases Send payments to beneficiaries: * Vendor payments * Refunds * Payroll * Disbursements ## Payment Methods **Supported Networks** * Visa * Mastercard **Transfer Types** * NGN bank transfers **Features** * Instant account verification * Automated reconciliation * Standing instructions * Bulk transfers **Supported Tokens** * USDC (ETH, MATIC, AVAXC) * USDT (ETH, TRX,AVAXC) **Features** * Multi-chain support * Automated rate conversion * Real-time settlements * Low transaction fees **Canadian Payments** * Payment link widget  * Direct e-transfer deposit * Interac Payment link ## Transaction Limits and Processing Times ### Card Payments **Transaction Limits** * Minimum: 100NGN, 5 CAD * Maximum per transaction: * NGN: 5,000,000 * CAD: 10,000 **Processing Times** * Standard transactions: Near instant * 3DS Authentication: 1-5 minutes * Refunds: 5-7 business days ### Bank Transfers **Transaction Limits** * Minimum: 100NGN, 4CAD * Maximum per transaction: * NGN: 10,000,000 * CAD: 50,000 **Processing Times** * NGN transfers: Almost Immediate * Interac -Almost immediate ### Stablecoins **Transaction Limits** * Minimum: 10 USDT/USDC * Maximum: 100,000 USDT/USDC per transaction **Processing Times by Network** * TRX: 1-3 minutes * ETH: 1-5 minutes * MATIC: 1-5 minutes * AVAXC: 1-5 minutes ### Interac e-Transfer **Transaction Limits** * Minimum: 5 CAD * Maximum: 10,000 CAD per transaction **Processing Times** * Incoming: 30 secs -2 minutes * Outgoing: 30 secs -2 minutes ### Payment Method Coverage * Global acceptance of Visa and Mastercard * Region-specific features and limits * 3DS requirements vary by jurisdiction * Local card processing where available * NGN: All major Nigerian banks * CAD: Via Interac only * Global availability * Restricted jurisdictions excluded * Multi-chain support * Cross-border capabilities ### Interac e-Transfer * Exclusive to Canadian market * Requires Canadian bank account * Supports both personal and business accounts * Available to all major Canadian financial institutions ## Supported Currencies Nigerian Naira * Local bank transfers * Card payments * Dynamic deposit Canadian Dollar * Interac e-Transfer * Local transfers * Card payments Transaction limits and processing times may vary based on: * Account verification status * Business type and history * Regional regulations * Risk assessment * Payment method selected Contact support for increased limits or special requirements. * Direct Debit payments * Mobile Money integration * Additional currency support * Enhanced payment features # Payment Widget Source: https://docs.juicyway.com/payments/payment-widget Integrate our secure payment widget into your platform ## Overview The Juicyway Payment Widget provides a pre-built, customizable checkout experience that you can easily embed into your website or application. This secure, user-friendly solution handles the entire payment flow while maintaining your brand identity. ## Key Features * **Quick Integration**: Simple implementation with minimal code * **Customizable UI**: Match your brand's look and feel * **Secure by Default**: PCI-compliant payment processing * **Multiple Payment Methods**: Support for cards, bank transfers, and more * **Responsive Design**: Works seamlessly on all devices ## Benefits Get up and running quickly with our pre-built solution Built-in security features and compliance standards Optimized checkout flow reduces abandonment Supports various implementation methods See our [Widget Integration Guide](/payments/payment-widget/widget-integration-guide) for detailed implementation instructions. # Widget Integration Guide Source: https://docs.juicyway.com/payments/payment-widget/widget-integration-guide Step-by-step guide to integrate the Juicyway Payment Widget This guide will walk you through the process of integrating the Juicyway Payment Widget into your application. ## Overview The Juicyway Payment Widget provides a secure and customizable payment solution that can be easily integrated into your website or application. Follow these steps to implement the widget in your platform. ## Integration Steps Add the following script tag to the `` section of your HTML: ```html theme={null} ``` Define a JavaScript function to initialize the payment widget: ```javascript theme={null} function openWidget() { Juicyway.PayWithJuice({ // Configuration options detailed below onClose: () => { // Called when user closes widget }, onSuccess: () => { // Called when payment is successful }, onError: (error) => { // Called when payment fails }, // Required parameters reference: "unique_ref_123", amount: 1000, currency: "USD", description: "Product purchase", isLive: true, key: "YOUR_API_KEY", order: { identifier: "ORDER123", items: [ { name: "E-book", type: "digital", qty: 1, amount: 1000 } ] }, // Optional parameters appName: "Your App Name", customer: { email: "customer@email.com", first_name: "Test", last_name: "Customer", phone_number: "+1234567890", billing_address: { line1: "123 Main St", city: "San Francisco", state: "CA", zip_code: "94105", country: "US" } }, paymentMethod: { type: "card" }, order: { // Additional payment order } }); } ``` Create a button or link that triggers the payment widget: ```html theme={null} ``` ## Configuration Parameters ### Required Parameters A unique identifier for the payment transaction The payment amount in the smallest denomination of the currency (e.g., cents for USD) A three-letter ISO 4217 currency code (e.g., USD, NGN, CAD) A short description of the payment Set to `true` for production environment, `false` for sandbox testing Your Juicyway API key Order details object containing: Unique identifier for the order Array of items in the order Name of the item Type of item (e.g., "digital", "physical") Quantity of the item Price per item ### Optional Parameters The name of your merchant's business or application Customer details object containing: Customer's email address Customer's first name Customer's last name Customer's phone number with country code Street address City State/Province Postal/ZIP code Two-letter country code Payment method configuration: Payment method type: "card" | "bank\_account" | "interac" Additional data related to the payment ## Callback Functions Called when the user closes the payment widget Called when the payment is successfully completed Called when an error occurs during payment processing For security purposes, always ensure you're using the correct API key for your environment (test or live). # Quickstart Guide Source: https://docs.juicyway.com/quickstart Get started with Juicyway API in minutes. This guide will help you start accepting payments with our API quickly and securely. Follow these steps to begin processing transactions. ## Step 1: Create Your Account Create your Juicyway business account: * For live transactions: [Production Dashboard](https://app.juicyway.com) * For testing: [Sandbox Dashboard](https://sandbox.juicyway.com/) After signing up: 1. Navigate to the KYC banner on the home page 2. Upload dummy data 3. Submit for immediate approval After signing up: 1. Navigate to Settings → API Keys. 2. Fetch test and live API keys. 3. Store keys securely - never expose them in client-side code. Configure webhooks to receive real-time payment updates: 1. Go to Settings → Webhooks 2. Add your webhook URL ## Step 2: Make Your First API Call Test your integration with this simple API call: ```bash cURL theme={null} curl -X POST "https://api-sandbox.spendjuice.com/payment-sessions" \ -H "Authorization: YOUR_TEST_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "customer": { "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone_number": "+2348118873422", "billing_address": { "line1": "123 Test Lane", "city": "Test City", "state": "Test State", "country": "NG", "zip_code": "12345" }, "ip_address": "127.0.0.1" }, "description": "Test Payment", "currency": "NGN", "amount": 100000, "payment_method": { "type": "card" }, "reference": "test-payment-123" }' ``` ```javascript Node.js theme={null} const axios = require('axios'); const response = await axios.post( 'https://api-sandbox.spendjuice.com/payment-sessions', { customer: { first_name: 'John', last_name: 'Doe', email: 'john.doe@example.com', phone_number: '+2348118873422', billing_address: { line1: '123 Test Lane', city: 'Test City', state: 'Test State', country: 'NG', zip_code: '12345' } }, description: 'Test Payment', currency: 'NGN', amount: 100000, payment_method: { type: 'card' }, reference: 'test-payment-123' }, { headers: { 'Authorization': ` YOUR_TEST_API_KEY`, 'Content-Type': 'application/json' } } ); ``` ```python Python theme={null} import requests response = requests.post( 'https://api-sandbox.spendjuice.com/payment-sessions', json={ 'customer': { 'first_name': 'John', 'last_name': 'Doe', 'email': 'john.doe@example.com', 'phone_number': '+2348118873422', 'billing_address': { 'line1': '123 Test Lane', 'city': 'Test City', 'state': 'Test State', 'country': 'NG', 'zip_code': '12345' } }, 'description': 'Test Payment', 'currency': 'NGN', 'amount': 100000, 'payment_method': { 'type': 'card' }, 'reference': 'test-payment-123' }, headers={ 'Authorization': ' YOUR_TEST_API_KEY', 'Content-Type': 'application/json' } ) ``` ## Step 3: Test Card Payments Use these test cards to simulate different payment scenarios: **VISA Test Card** * Card Number: 4012000033330026 * Expiry: 01/39 * CVV: 100 **Failed Card** * Card Number: 4000000000000002 * Expiry: 01/25 * CVV: 100 **3DS Card** * Card Number: 4761530000000008 * Expiry: 05/25 * CVV: 100 * Test OTP: 123456 ## Step 4: Handle Webhooks Set up webhook handling to receive real-time payment updates. Here's a basic example: ```javascript theme={null} app.post('/webhooks', (req, res) => { const payload = req.body; const checksum = payload.checksum; const businessId = process.env.BUSINESS_ID; // Validate webhook signature if (!validateSignature(payload, checksum, businessId)) { return res.status(401).send('Invalid signature'); } // Handle different event types switch(payload.event) { case 'payment.session.succeeded': // Handle successful payment break; case 'payment.session.failed': // Handle failed payment break; } res.status(200).send('Webhook received'); }); ``` ## Next Steps 1. Review our [API Authentication](/authentication) guide for secure API access 2. Set up comprehensive [Webhook Handling](/webhooks) 3. Learn about [Error Handling](/errors) 4. Explore supported [Payment Methods](/payments/overview) For additional assistance: * Review our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Add contact to a market maker Source: https://docs.juicyway.com/reference/exchange/add-contact-to-a-market-maker /openapi.json patch /exchange/market-makers/{id}/add-contact # Cancel an order Source: https://docs.juicyway.com/reference/exchange/cancel-an-order /openapi.json put /exchange/orders/{id}/cancel # Convert an amount from one currency to another Source: https://docs.juicyway.com/reference/exchange/convert-an-amount-from-one-currency-to-another /openapi.json post /exchange/convert # Create a market maker Source: https://docs.juicyway.com/reference/exchange/create-a-market-maker /openapi.json post /exchange/market-makers # Create a rate Source: https://docs.juicyway.com/reference/exchange/create-a-rate /openapi.json post /exchange/rates # Create a standing order Source: https://docs.juicyway.com/reference/exchange/create-a-standing-order /openapi.json post /exchange/standing-orders # Create a swap configuration Source: https://docs.juicyway.com/reference/exchange/create-a-swap-configuration /openapi.json post /exchange/swap-configurations # Create an order Source: https://docs.juicyway.com/reference/exchange/create-an-order /openapi.json post /exchange/orders # Delete a rate Source: https://docs.juicyway.com/reference/exchange/delete-a-rate /openapi.json delete /exchange/rates/{id} # Delete a standing order Source: https://docs.juicyway.com/reference/exchange/delete-a-standing-order /openapi.json delete /exchange/standing-orders/{id} # Delete a swap configuration Source: https://docs.juicyway.com/reference/exchange/delete-a-swap-configuration /openapi.json delete /exchange/swap-configurations/{id} # Fetch current market prices Source: https://docs.juicyway.com/reference/exchange/fetch-current-market-prices /openapi.json get /exchange/market-prices{symbol} # Get order book Source: https://docs.juicyway.com/reference/exchange/get-order-book /openapi.json get /exchange/books/{symbol} # Get rate Source: https://docs.juicyway.com/reference/exchange/get-rate /openapi.json get /exchange/rates/{id} # Get swap Source: https://docs.juicyway.com/reference/exchange/get-swap /openapi.json get /exchange/swap/{id} # Get swap rate Source: https://docs.juicyway.com/reference/exchange/get-swap-rate /openapi.json get /exchange/swap/rate # Increase order book liquidity Source: https://docs.juicyway.com/reference/exchange/increase-order-book-liquidity /openapi.json post /exchange/increase-liquidity # List currencies Source: https://docs.juicyway.com/reference/exchange/list-currencies /openapi.json get /exchange/currencies # List market makers Source: https://docs.juicyway.com/reference/exchange/list-market-makers /openapi.json get /exchange/market-makers # List orders Source: https://docs.juicyway.com/reference/exchange/list-orders /openapi.json get /exchange/orders # List rates Source: https://docs.juicyway.com/reference/exchange/list-rates /openapi.json get /exchange/rates # List standing orders Source: https://docs.juicyway.com/reference/exchange/list-standing-orders /openapi.json get /exchange/standing-orders # List supported rates Source: https://docs.juicyway.com/reference/exchange/list-supported-rates /openapi.json get /exchange/pairs # List swap configuration Source: https://docs.juicyway.com/reference/exchange/list-swap-configuration /openapi.json get /exchange/swap-configurations # List swaps Source: https://docs.juicyway.com/reference/exchange/list-swaps /openapi.json get /exchange/swap # Make a swap Source: https://docs.juicyway.com/reference/exchange/make-a-swap /openapi.json post /exchange/swap # Remove contact from a market maker Source: https://docs.juicyway.com/reference/exchange/remove-contact-from-a-market-maker /openapi.json patch /exchange/market-makers/{id}/remove-contact # Retrieve a market maker Source: https://docs.juicyway.com/reference/exchange/retrieve-a-market-maker /openapi.json get /exchange/market-makers/{id} # Retrieve a standing order Source: https://docs.juicyway.com/reference/exchange/retrieve-a-standing-order /openapi.json get /exchange/standing-orders/{id} # Retrieve a swap configuration Source: https://docs.juicyway.com/reference/exchange/retrieve-a-swap-configuration /openapi.json get /exchange/swap-configurations/{id} # Retrieve an order Source: https://docs.juicyway.com/reference/exchange/retrieve-an-order /openapi.json get /exchange/orders/{id} # Retrieve list of orders created from a standing order Source: https://docs.juicyway.com/reference/exchange/retrieve-list-of-orders-created-from-a-standing-order /openapi.json get /exchange/standing-orders/{id}/orders # Retrieve market maker details for current account Source: https://docs.juicyway.com/reference/exchange/retrieve-market-maker-details-for-current-account /openapi.json get /exchange/market-makers/me # Update a market maker Source: https://docs.juicyway.com/reference/exchange/update-a-market-maker /openapi.json patch /exchange/market-makers/{id} # Update a rate Source: https://docs.juicyway.com/reference/exchange/update-a-rate /openapi.json patch /exchange/rates/{id} # Update a standing order Source: https://docs.juicyway.com/reference/exchange/update-a-standing-order /openapi.json patch /exchange/standing-orders/{id} # Update a swap configuration Source: https://docs.juicyway.com/reference/exchange/update-a-swap-configuration /openapi.json patch /exchange/swap-configurations/{id} # Fetch current market prices Source: https://docs.juicyway.com/reference/orders/fetch-current-market-prices /openapi.json get /exchange/market-prices # Authorize a captured payment session Source: https://docs.juicyway.com/reference/payments/authorize-a-captured-payment-session /openapi.json post /payment-sessions/{id}/authorize # Cancel a running payment session Source: https://docs.juicyway.com/reference/payments/cancel-a-running-payment-session /openapi.json post /payment-sessions/{id}/cancel # Capture a payment session Source: https://docs.juicyway.com/reference/payments/capture-a-payment-session /openapi.json post /payment-sessions/{id} # Create a payment link Source: https://docs.juicyway.com/reference/payments/create-a-payment-link /openapi.json post /payment-links # Export payment details Source: https://docs.juicyway.com/reference/payments/export-payment-details /openapi.json get /payments/export # Get a hosted payment session Source: https://docs.juicyway.com/reference/payments/get-a-hosted-payment-session /openapi.json get /hosted-sessions/{id} # Get a payment link Source: https://docs.juicyway.com/reference/payments/get-a-payment-link /openapi.json get /payment-links/{id} # Get a running payment session Source: https://docs.juicyway.com/reference/payments/get-a-running-payment-session /openapi.json get /payment-sessions/{id} # Get encryption key Source: https://docs.juicyway.com/reference/payments/get-encryption-key /openapi.json get /payment-sessions/encryption-keys/{mode} # Get merchant profile Source: https://docs.juicyway.com/reference/payments/get-merchant-profile /openapi.json get /merchants/me # Get merchant profile Source: https://docs.juicyway.com/reference/payments/get-merchant-profile-1 /openapi.json patch /merchants/me/settings # Get payment details Source: https://docs.juicyway.com/reference/payments/get-payment-details /openapi.json get /payments # Get payment details Source: https://docs.juicyway.com/reference/payments/get-payment-details-1 /openapi.json get /payments/{id} # Get payment stats Source: https://docs.juicyway.com/reference/payments/get-payment-stats /openapi.json get /payments/stats # Initialize a payment session Source: https://docs.juicyway.com/reference/payments/initialize-a-payment-session /openapi.json post /payment-sessions # Initiate a payment refund Source: https://docs.juicyway.com/reference/payments/initiate-a-payment-refund /openapi.json post /payments/{id}/refund # List payment links Source: https://docs.juicyway.com/reference/payments/list-payment-links /openapi.json get /payment-links # Retry the processing of a pending outgoing payment Source: https://docs.juicyway.com/reference/payments/retry-the-processing-of-a-pending-outgoing-payment /openapi.json post /payments/retry # Update a payment link Source: https://docs.juicyway.com/reference/payments/update-a-payment-link /openapi.json patch /payment-links/{id} # Update a pending payment session Source: https://docs.juicyway.com/reference/payments/update-a-pending-payment-session /openapi.json patch /payment-sessions/{id} # Update merchant profile Source: https://docs.juicyway.com/reference/payments/update-merchant-profile /openapi.json patch /merchants/me # Add transfers Source: https://docs.juicyway.com/reference/payouts/add-transfers /openapi.json post /bulk-transfers/transfers # cancel bulk transfer Source: https://docs.juicyway.com/reference/payouts/cancel-bulk-transfer /openapi.json post /bulk-transfers/{id}/cancel # Delete transfers Source: https://docs.juicyway.com/reference/payouts/delete-transfers /openapi.json delete /bulk-transfers/{batch_id}/transfers/{id} # Execute bulk transfer Source: https://docs.juicyway.com/reference/payouts/execute-bulk-transfer /openapi.json post /bulk-transfers/{id}/execute # Generate a payout receipt Source: https://docs.juicyway.com/reference/payouts/generate-a-payout-receipt /openapi.json get /payouts/{id}/receipt # Get bulk payout details Source: https://docs.juicyway.com/reference/payouts/get-bulk-payout-details /openapi.json get /bulk-transfers/{id} # Get charge for a payout Source: https://docs.juicyway.com/reference/payouts/get-charge-for-a-payout /openapi.json get /payouts/charge # Get payout details Source: https://docs.juicyway.com/reference/payouts/get-payout-details /openapi.json get /payouts/{id} # Initiate a bulk transfer Source: https://docs.juicyway.com/reference/payouts/initiate-a-bulk-transfer /openapi.json post /bulk-transfers # Initiate a payout Source: https://docs.juicyway.com/reference/payouts/initiate-a-payout /openapi.json post /payouts # List bulk payouts Source: https://docs.juicyway.com/reference/payouts/list-bulk-payouts /openapi.json get /bulk-transfers # List payouts Source: https://docs.juicyway.com/reference/payouts/list-payouts /openapi.json get /payouts # Retry failed but retryable transfer Source: https://docs.juicyway.com/reference/payouts/retry-failed-but-retryable-transfer /openapi.json post /bulk-transfers/{batch_id}/transfers/{id}/retry # Get aggregator swap rate Source: https://docs.juicyway.com/reference/swaps/get-aggregator-swap-rate /openapi.json get /exchange/fx/rate # Get quote Source: https://docs.juicyway.com/reference/swaps/get-quote /openapi.json get /exchange/quote # Get swap by reference Source: https://docs.juicyway.com/reference/swaps/get-swap-by-reference /openapi.json get /exchange/fx/convert/{reference} # Lock aggregator swap rate Source: https://docs.juicyway.com/reference/swaps/lock-aggregator-swap-rate /openapi.json post /exchange/fx/rate/{id}/lock # Lock quote Source: https://docs.juicyway.com/reference/swaps/lock-quote /openapi.json post /exchange/quote/{id}/lock # Make a swap with a locked aggregator rate Source: https://docs.juicyway.com/reference/swaps/make-a-swap-with-a-locked-aggregator-rate /openapi.json post /exchange/fx/convert # Create a wallet Source: https://docs.juicyway.com/reference/wallets/create-a-wallet /openapi.json post /wallets # Create a wallet payment method Source: https://docs.juicyway.com/reference/wallets/create-a-wallet-payment-method /openapi.json post /wallets/{id}/payment-method # Create a wallet transaction Source: https://docs.juicyway.com/reference/wallets/create-a-wallet-transaction /openapi.json post /wallets/transactions # List transactions Source: https://docs.juicyway.com/reference/wallets/list-transactions /openapi.json get /wallets/transactions # List wallets Source: https://docs.juicyway.com/reference/wallets/list-wallets /openapi.json get /wallets/all # Retrieve a wallet Source: https://docs.juicyway.com/reference/wallets/retrieve-a-wallet /openapi.json get /wallets/{id} # Retrieve a wallet transaction Source: https://docs.juicyway.com/reference/wallets/retrieve-a-wallet-transaction /openapi.json get /wallets/transactions/{id} # Update a wallet status Source: https://docs.juicyway.com/reference/wallets/update-a-wallet-status /openapi.json patch /wallets/{id}/status # Update wallet balance Source: https://docs.juicyway.com/reference/wallets/update-wallet-balance /openapi.json patch /wallets/{id}/balance # Beneficiaries Source: https://docs.juicyway.com/transfers/beneficiaries Manage and store transfer recipients for quick, secure payouts ## Overview Beneficiaries are pre-validated recipients for your transfers. Managing beneficiaries enables you to: * Store recipient details securely * Validate account information upfront * Execute transfers quickly and safely * Maintain an auditable recipient database ## Supported Beneficiary Types **Features** * Multiple currency support * Account validation * Local & international transfers * Automated verification **Features** * Multiple chain support * Address validation * Network detection * Chain verification **Features** * Email/phone association * Auto-deposit support * Canadian accounts only * Real-time validation **Coming Soon** * Multiple providers * Number validation * Regional support * Instant verification ## Beneficiary Information ### Bank Account Beneficiaries Bank account number Account holder name Bank routing/sort code Account currency (e.g., NGN, USD, CAD) ### Crypto Address Beneficiaries Wallet address Blockchain network (ETH, TRX, etc.) Token currency (USDT, USDC) ### Interac Recipients Recipient email First name Last name Optional phone number ## Key Operations Add new transfer recipients with validated details. See [Create Beneficiary](/transfers/beneficiaries/create-beneficiary). Fetch beneficiary information by ID. See [Fetch Beneficiary](/transfers/beneficiaries/fetch-beneficiary). Get a paginated list of all beneficiaries. See [List Beneficiaries](/transfers/beneficiaries/list-beneficiaries). ## Validation Rules * Account numbers must be valid for the specified bank * Account name must match bank records * Bank code must be valid for the country * Currency must be supported for the bank * Address must be valid for the specified chain * Chain must support the selected token * Address checksum verification * Network compatibility check * Valid Canadian email format * Registered for Interac e-Transfer * Optional phone number in Canadian format * Name matching verification ## Best Practices 1. **Validation** * Verify recipient details before creation * Test transfer with small amounts * Implement proper error handling * Monitor validation responses 2. **Security** * Store beneficiary IDs, not details * Validate all input data * Implement access controls * Monitor for suspicious patterns 3. **Management** * Regular beneficiary verification * Clean up unused beneficiaries * Track failed validations * Monitor success rates Learn how to: * [Create Beneficiaries](/transfers/beneficiaries/create-beneficiary) * [Fetch Beneficiary Details](/transfers/beneficiaries/fetch-beneficiary) * [List All Beneficiaries](/transfers/beneficiaries/list-beneficiaries) # Create Beneficiary Source: https://docs.juicyway.com/transfers/beneficiaries/create-beneficiary Create and save beneficiaries for transfers across multiple payment methods ## Overview The Create Beneficiary endpoint allows you to save recipient information for future transfers. You can create beneficiaries for bank accounts, crypto wallets, and Interac e-Transfer recipients. Saved beneficiaries can be reused for future transfers without having to re-enter the recipient details each time. ## Endpoint ```bash theme={null} POST /beneficiaries ``` ## Supported Beneficiary Types * NGN bank accounts * USD bank accounts (ACH/Wire) * International bank accounts * USDT addresses * USDC addresses * Multiple chains such as AVAX, ETH, TRX, DOGE, ADA, SOL are supported * Canadian recipients via Interac ## Create NGN Bank Account Beneficiary ### Request Parameters Must be "bank\_account" Must be "NGN" Account holder's name as registered with bank 10-digit Nigerian bank account number Full bank name Bank's unique code - get from [List Banks](/transfers/transfers/list-ngn-banks) endpoint Must be nuban ### Example Request ```json theme={null} { "type": "bank_account", "currency": "NGN", "account_name": "John Doe", "account_number": "0123456789", "bank_name": "First Bank of Nigeria", "bank_code": "011", "rail": "nuban" } ``` ## Create USD Bank Account Beneficiary ### Request Parameters Must be "bank\_account" Must be "USD" 9-digit ABA routing number Payment rail to use ("ach" or "wire") Bank sort code (if required) Beneficiary's address information Street address Additional address info City name State code 2-letter country code ZIP/Postal code Bank's physical address Street address Additional address info City name State code 2-letter country code ZIP/Postal code ### Example Request ```json theme={null} { "type": "bank_account", "currency": "USD", "routing_number": "123456789", "rail": "ach", "sort_code": "123456", "address": { "line1": "15 High Road", "line2": "Unit 12", "city": "New York", "state": "NY", "country": "US", "zip_code": "10003" }, "bank_address": { "line1": "20 Finance Blvd", "line2": "Suite 200", "city": "Los Angeles", "state": "CA", "country": "US", "zip_code": "90001" } } ``` ## Create Interac e-Transfer Beneficiary ### Request Parameters Must be "interac" Must be "CAD" Type of recipient ("personal" or "business") Recipient's first name Recipient's last name Recipient's email registered with Interac Recipient's phone number (optional) Security question for manual deposits Answer to security question ### Example Request ```json theme={null} { "type": "interac", "currency": "CAD", "beneficiary_type": "personal", "first_name": "Alice", "last_name": "Smith", "email": "alice@example.com", "question": "What is your pet's name?", "answer": "Fluffy", "phone_number": "1234567890" } ``` ## Create Crypto Address Beneficiary ### Request Parameters Must be "crypto\_address" Must be one of `USDC`, `USDT` Multiple chains such as AVAX, ETH, TRX, DOGE, ADA, SOL are supported Must be a supported crypto address based on the currency and chain ### Example Request ```json theme={null} { "type": "crypto_address", "label": "Test wallet", "currency": "USDC|USDT", "chain": "ETH|TRX|DOGE|ADA|SOL|AVAX", "address": "0x..." } ``` ## Response Format Created beneficiary details Unique beneficiary identifier Beneficiary type Currency code For bank accounts: Account holder name For bank accounts: Account number For bank accounts: Account type For bank accounts: Bank name For bank accounts: Bank code For USD accounts: ABA routing number ID of creating user ### Success Response Example ```json theme={null} { "data": { "account_name": "Michael Asaju", "account_number": "8036120312", "account_type": "savings", "address": null, "bank_address": null, "bank_code": "100004", "bank_id": null, "bank_name": "OPAY", "bic": null, "currency": "NGN", "id": "d71efb6e-b7f5-4acd-a729-3da08e36eaed", "lifetime": "permanent", "routing_number": null, "sort_code": null, "type": "bank_account", "user_id": "c545cbc5-9915-4bfb-98ee-3759894feac2", "virtual": false } } ``` ## Error Handling ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid parameters provided", "details": { "account_number": ["Invalid account number format"] } } } ``` ```json theme={null} { "error": { "code": "validation_error", "message": "Invalid beneficiary details", "details": { "routing_number": ["Must be 9 digits for US banks"] } } } ``` ```json theme={null} { "error": { "code": "duplicate_beneficiary", "message": "A beneficiary with these details already exists" } } ``` ## Validation Rules 1. **NGN Bank Accounts** * Account numbers must be 10 digits * Bank code must be valid * Account name must match bank records 2. **USD Bank Accounts** * Routing numbers must be 9 digits * Valid US state codes required * ZIP codes must match state 3. **Interac e-Transfer** * Valid Canadian email required * Security question required if auto-deposit not enabled * Phone number must be Canadian format For additional assistance: * Check our [API Reference](/api-reference/overview) * Contact [Support](mailto:support@juicyway.com) * Review our [Error Handling Guide](/errors) # Fetch Beneficiary Source: https://docs.juicyway.com/transfers/beneficiaries/fetch-beneficiary Retrieve a Specific Beneficiary ## **Request Parameters** The following fields are required to retrieve a specific beneficiary: * **`type`** (Object, Required): Specifies the type of the request object. * **`after`** (String, Required): A cursor indicating the starting point for pagination. * **`before`** (String, Required): A cursor indicating the ending point for pagination. * **`limit`** (Integer, Required): The maximum number of records to return in the response. * **`user_id`** (String, Required): The unique identifier of the user associated with the beneficiary. * **`account_id`** (String, Required): The unique identifier of the account associated with the beneficiary. ## Initialization To retrieve a specific beneficiary, ensure all required fields are included in the request. ```json theme={null} GET /beneficiaries/{id} ``` **Sample Response** ```json theme={null} { "data":{ "account_name": "MICHAEL ENITAN ASAJU", "account_number": "0821081314", "account_type": "savings", "address": {}, "bank_address": {}, "bank_code": "000014", "bank_id": "", "bank_name": "ACCESS BANK", "bic": null, "currency": "NGN", "id": "d8c0226b-048c-4c44-9606-a93333f56283", "lifetime": "permanent", "routing_number": null, "sort_code": null, "type": "bank_account", "user_id": "c545cbc5-9915-4bfb-98ee-3759894feac2", "virtual": false } } ``` #### Notes * Ensure the `after` and `before` cursors are correctly formatted to avoid pagination errors. * The `limit` value must be a positive integer and should not exceed the system's maximum allowed limit. * The `user_id` and `account_id` must correspond to valid and existing records in the system. * The response includes detailed information about the beneficiary, such as account details, bank information, and associated metadata. # List Beneficiaries Source: https://docs.juicyway.com/transfers/beneficiaries/list-beneficiaries Retrieve a paginated list of beneficiaries associated with your account. This endpoint supports filtering and sorting options to help you manage large numbers of beneficiaries efficiently. ```bash theme={null} GET /beneficiaries ``` ## Query Parameters Number of records to return per page (max: 100) Cursor for fetching next page of results Cursor for fetching previous page of results Filter by currency (e.g., NGN, USD, CAD) Filter by beneficiary type (e.g., bank\_account, crypto\_address) ## Response Object Array of beneficiary objects Unique identifier for the beneficiary Type of beneficiary (bank\_account, crypto\_address) Currency code for the beneficiary account Name on the bank account (for bank\_account type) Account number (for bank\_account type) Bank name (for bank\_account type) Bank identifier code Whether this is a virtual account Duration of beneficiary validity Cursor for the previous page Cursor for the next page Current page size ## Examples ### List All Beneficiaries ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/beneficiaries?limit=2" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/beneficiaries?limit=2', { headers: { 'Authorization': ' YOUR_API_KEY' } } ); ``` ```python Python theme={null} import requests response = requests.get( 'https://api.spendjuice.com/beneficiaries', params={'limit': 2}, headers={'Authorization': ' YOUR_API_KEY'} ) ``` ### Success Response ```json theme={null} { "data": [ { "account_name": "MICHAEL ENITAN ASAJU", "account_number": "0821081314", "account_type": "savings", "address": null, "bank_address": null, "bank_code": "000014", "bank_id": null, "bank_name": "ACCESS BANK", "bic": null, "currency": "NGN", "id": "d8c0226b-048c-4c44-9606-a93333f56283", "lifetime": "permanent", "routing_number": null, "sort_code": null, "type": "bank_account", "user_id": "c545cbc5-9915-4bfb-98ee-3759894feac2", "virtual": false }, { "account_name": "Michael Asaju", "account_number": "8036120312", "account_type": "savings", "address": null, "bank_address": null, "bank_code": "100004", "bank_id": null, "bank_name": "OPAY", "bic": null, "currency": "NGN", "id": "d71efb6e-b7f5-4acd-a729-3da08e36eaed", "lifetime": "permanent", "routing_number": null, "sort_code": null, "type": "bank_account", "user_id": "c545cbc5-9915-4bfb-98ee-3759894feac2", "virtual": false } ], "pagination": { "after": "d71efb6e-b7f5-4acd-a729-3da08e36eaed", "before": null, "limit": 2 } } ``` ## Pagination The API uses cursor-based pagination. To fetch subsequent pages: 1. Get the `after` cursor from the pagination object 2. Include it in your next request 3. Repeat until no more `after` cursor is returned For optimal performance: * Use reasonable page sizes (15-50 records) * Cache results when possible * Implement progressive loading in your UI ## Error Responses ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid query parameters", "details": { "limit": ["Must be between 1 and 100"] } } } ``` ```json theme={null} { "error": { "code": "unauthorized", "message": "Invalid or missing API key" } } ``` ## Best Practices 1. **Efficient Filtering** * Use filters to reduce response size * Combine filters for precise results * Cache frequently accessed data 2. **Pagination Handling** * Store cursors temporarily for navigation * Implement infinite scroll for large lists * Show loading states during fetches 3. **Error Handling** * Implement proper retry logic * Handle rate limits gracefully * Log pagination errors For additional assistance: * Check our [Error Handling Guide](/errors) * Contact [Support](mailto:support@juicyway.com) # Cancel Bulk Transfer Source: https://docs.juicyway.com/transfers/bulk-transfers/cancel-bulk-transfer Cancel a pending bulk transfer or individual transfers within a batch ## Overview The Cancel Bulk Transfer endpoint allows you to stop a pending bulk transfer from being processed. You can cancel the entire batch or specific transfers within it, depending on their current status. Only bulk transfers in `created` or `executing` status can be cancelled. Completed, expired, or already cancelled transfers cannot be modified. ## Endpoint ```bash theme={null} POST /bulk-transfers/{id}/cancel ``` ## Path Parameters The unique identifier of the bulk transfer to cancel ## Request Example ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297/cancel" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297/cancel', { method: 'POST', headers: { 'Authorization': ' YOUR_API_KEY' } } ); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.spendjuice.com/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297/cancel', headers={'Authorization': ' YOUR_API_KEY'} ) ``` ## Response Examples ```json 200 Success theme={null} { "data": { "created_at": "2024-10-02T17:39:26.049258", "description": "Monthly Vendor Payments", "expires_at": "2024-10-03T17:39:25Z", "failed_transfer_count": 0, "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "items": [], "metadata": {}, "owner": { "id": "65fb1bf9-10e7-4556-8005-0c3249b8df36", "type": "personal" }, "reference": "46f3ef38-22de-4498-a6d3-13749aa2a0a7", "status": "cancelled", "successful_transfer_count": 0, "total_transfer_count": 0, "updated_at": "2024-10-02T17:39:26Z" } } ``` ```json 404 Not Found theme={null} { "error": { "code": "bulk_transfer_not_found", "message": "No bulk transfer found with ID: 7d528558-1c20-4bb6-9a9a-a03c8292b297" } } ``` ```json 409 Conflict theme={null} { "error": { "code": "invalid_state", "message": "Bulk transfer cannot be cancelled in its current state" } } ``` ## Status Transitions When you cancel a bulk transfer: 1. Status changes from `created`/`executing` to `cancelled` 2. All pending transfers are marked as `cancelled` 3. In-progress transfers complete normally 4. Completed transfers remain unchanged ## Webhook Events Monitor these events for cancellation status: Fired when the bulk transfer is successfully cancelled ```json theme={null} { "event": "bulk_transfer.cancelled", "data": { "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "status": "cancelled", "cancelled_at": "2024-10-02T18:00:00Z", "cancelled_transfers": 5, "completed_transfers": 2 } } ``` Fired for each cancelled transfer in the batch ```json theme={null} { "event": "bulk_transfer.transfer.cancelled", "data": { "bulk_transfer_id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "transfer_id": "tr_123abc", "status": "cancelled", "cancelled_at": "2024-10-02T18:00:00Z" } } ``` ## Error Handling The specified bulk transfer doesn't exist * Verify the bulk transfer ID * Check the ID format Transfer cannot be cancelled in current state * Only created/executing transfers can be cancelled * Check current transfer status Some transfers could not be cancelled * In-progress transfers will complete * Check individual transfer statuses ## Refund Handling For transfers that require refunds: 1. Successfully cancelled transfers are automatically reversed 2. Funds are returned to your balance 3. Refund status is tracked via webhooks 4. Processing time varies by payment method Some payment methods may have specific refund restrictions or processing times. ## Best Practices 1. **Pre-cancellation Checks** * Verify bulk transfer status * Check for in-progress transfers * Consider timing of cancellation 2. **Monitoring** * Implement webhook handling * Track cancellation status * Monitor refund processing 3. **Error Handling** * Handle partial cancellations * Implement retry logic * Log cancellation attempts For additional assistance: * Review [Error Handling Guide](/errors) * Contact [Support](mailto:support@juicyway.com) * Check [Webhook Documentation](/webhooks) # Delete from Bulk Transfer Source: https://docs.juicyway.com/transfers/bulk-transfers/delete-bulk-transfer Remove individual transfers from a bulk transfer batch before execution ## Overview The Delete Transfer endpoint allows you to remove individual transfers from a bulk transfer batch that hasn't been executed. This is useful for correcting errors or removing unnecessary transfers before batch execution. You can only delete transfers from batches that are in the `created` status. Once a batch is executing or completed, transfers cannot be deleted. ## Endpoint ```bash theme={null} DELETE /bulk-transfers/{batch_id}/transfers/{id} ``` ## Path Parameters The unique identifier of the bulk transfer batch * Must be a valid UUID * Batch must be in `created` status The unique identifier of the transfer to delete * Must be a valid UUID * Transfer must be part of the specified batch ## Request Example ```bash cURL theme={null} curl -X DELETE "https://api.spendjuice.com/bulk-transfers/88dbcb86-5025-4ac9-9750-4aa5a77a723c/transfers/e2df31d2-828e-11ef-8f08-acde48001122" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/bulk-transfers/88dbcb86-5025-4ac9-9750-4aa5a77a723c/transfers/e2df31d2-828e-11ef-8f08-acde48001122', { method: 'DELETE', headers: { 'Authorization': ' YOUR_API_KEY' } } ); ``` ```python Python theme={null} import requests response = requests.delete( 'https://api.spendjuice.com/bulk-transfers/88dbcb86-5025-4ac9-9750-4aa5a77a723c/transfers/e2df31d2-828e-11ef-8f08-acde48001122', headers={'Authorization': ' YOUR_API_KEY'} ) ``` ## Response A successful delete operation returns an HTTP 204 (No Content) response with no response body. ## Error Responses ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid batch or transfer ID format" } } ``` ```json theme={null} { "error": { "code": "not_found", "message": "Transfer or batch not found" } } ``` ```json theme={null} { "error": { "code": "invalid_state", "message": "Cannot delete transfer from batch in current status" } } ``` ## Validation Rules 1. **Batch Status** * Only transfers in batches with `created` status can be deleted * Deletion blocked if batch is executing/completed * Batch must belong to your account 2. **Transfer Requirements** * Transfer must exist in the specified batch * Transfer must not be in processing state * Transfer ID must be valid format ## Status Impact Deleting a transfer: * Reduces the batch's total transfer count * Updates batch metadata * Cannot be undone - requires re-adding if needed * Does not affect other transfers in the batch ## Best Practices 1. **Validation** * Verify batch and transfer status before deletion * Handle expected error cases gracefully * Log deletion attempts for audit purposes 2. **Error Handling** * Implement retry logic for network errors * Show clear error messages to users * Monitor deletion success rates 3. **Security** * Validate user permissions * Log all deletion operations * Implement rate limiting * Use HTTPS for all requests For additional assistance: * Check our [Error Handling Guide](/errors) * Review [Bulk Transfer Overview](/transfers/bulk-transfers/overview) * Contact [Support](mailto:support@juicyway.com) # Execute Bulk Transfer Source: https://docs.juicyway.com/transfers/bulk-transfers/execute-bulk-transfer Execute a prepared bulk transfer by triggering the payment process for all included transfers ## Overview The Execute Bulk Transfer endpoint initiates the processing of all transfers within a prepared bulk transfer batch. This operation transitions the bulk transfer from `created` status to `executing` and begins processing individual transfers. Before executing a bulk transfer: 1. Ensure all transfer details are correct 2. Verify sufficient balance for all transfers 3. Check that the bulk transfer hasn't expired 4. Confirm no validation errors in transfer items ## Endpoint ```http theme={null} POST /bulk-transfers/{id}/execute ``` ### Path Parameters The unique identifier of the bulk transfer to execute * Must be in `created` status * Must not be expired * Must have at least one valid transfer ## Prerequisites Before execution can begin: * All transfers must have valid beneficiary details * Total transfer amount must not exceed your limits * Your account must have sufficient balance * The bulk transfer must not be expired * No pending validation issues ## Example Request ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297/execute" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297/execute', { method: 'POST', headers: { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } } ); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.spendjuice.com/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297/execute', headers={ 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' } ) ``` ## Response Format ### Success Response (202 Accepted) ```json theme={null} { "data": { "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "status": "executing", "total_transfer_count": 10, "successful_transfer_count": 0, "failed_transfer_count": 0, "created_at": "2024-03-15T10:30:00Z", "updated_at": "2024-03-15T10:35:00Z", "execution_started_at": "2024-03-15T10:35:00Z" } } ``` ## Status Transitions When a bulk transfer is executed, it goes through these status changes: Initial transition when execution begins All transfers processed successfully Some transfers succeeded, some failed All transfers failed to process ## Webhook Events Monitor these webhook events for bulk transfer status: Triggered when execution begins ```json theme={null} { "event": "bulk_transfer.executing", "data": { "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "status": "executing", "total_transfer_count": 10 } } ``` Triggered when all transfers complete successfully ```json theme={null} { "event": "bulk_transfer.completed", "data": { "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "status": "completed", "successful_transfer_count": 10, "failed_transfer_count": 0 } } ``` Triggered if execution fails ```json theme={null} { "event": "bulk_transfer.failed", "data": { "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "status": "failed", "error": { "code": "insufficient_balance", "message": "Insufficient balance for transfer" } } } ``` ## Error Handling Bulk transfer is not in executable state * Status code: 400 * Must be in `created` status Insufficient balance for transfers * Status code: 400 * Check available balance Bulk transfer has expired * Status code: 400 * Create new bulk transfer One or more transfers invalid * Status code: 422 * Fix validation issues first ## Rate Limits Bulk transfer execution is subject to these limits: * Maximum 1 execution request per bulk transfer * Maximum 100 transfers per bulk transfer * Maximum 10 concurrent executing bulk transfers ## Best Practices 1. **Pre-execution Validation** * Verify all beneficiary details * Check sufficient balance * Validate transfer amounts * Monitor expiration time 2. **Error Handling** * Implement webhook handling * Monitor individual transfer status * Handle partial completions * Log execution attempts 3. **Monitoring** * Track execution progress * Monitor success rates * Set up alerts for failures * Review execution logs For additional assistance: * Check our [Webhooks Guide](/webhooks) * Review [Error Handling](/errors) * Contact [Support](mailto:support@juicyway.com) # Get Bulk Transfer Details Source: https://docs.juicyway.com/transfers/bulk-transfers/get-bulk-transfer-details Retrieve detailed information about a specific bulk transfer including its status, items, and execution results ## Overview The Get Bulk Transfer Details endpoint allows you to retrieve comprehensive information about a specific bulk transfer including its current status, all included transfers, success/failure counts, and execution results. ## Endpoint ```bash theme={null} GET /bulk-transfers/{id} ``` ## Path Parameters The unique identifier of the bulk transfer to retrieve * Format: UUID v4 * Example: `7d528558-1c20-4bb6-9a9a-a03c8292b297` ## Response Format Unique identifier for the bulk transfer User-provided description of the bulk transfer Current status of the bulk transfer. One of: * `created` - Initial state * `executing` - Transfers in progress * `completed` - All transfers processed * `cancelled` - Manually cancelled * `expired` - Past expiration date ISO 8601 timestamp of creation ISO 8601 timestamp of last update ISO 8601 timestamp when transfer expires Optional additional data for the bulk transfer Details about the transfer owner Owner's unique identifier Owner type (e.g., "personal", "business") Array of individual transfers in this batch Your unique reference for this bulk transfer Total number of transfers in the batch Number of successfully completed transfers Number of failed transfers ## Example Request ```bash cURL theme={null} curl -X GET "https://payout-staging.spendjuice.com/v1/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://payout-staging.spendjuice.com/v1/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297', { headers: { 'Authorization': ' YOUR_API_KEY' } } ); ``` ```python Python theme={null} import requests response = requests.get( 'https://payout-staging.spendjuice.com/v1/bulk-transfers/7d528558-1c20-4bb6-9a9a-a03c8292b297', headers={'Authorization': ' YOUR_API_KEY'} ) ``` ## Response Examples ```json 200 Success theme={null} { "data": { "created_at": "2024-10-02T17:39:26.049258", "description": "October Vendor Payments", "expires_at": "2024-10-03T17:39:25Z", "failed_transfer_count": 0, "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "items": [ { "amount": 100000, "beneficiary": { "account_name": "ACME Corp", "account_number": "0123456789", "bank_name": "Example Bank" }, "status": "pending", "created_at": "2024-10-02T17:39:26Z", "reference": "vendor_payment_123" } ], "metadata": { "department": "finance", "batch_id": "OCT2024_001" }, "owner": { "id": "65fb1bf9-10e7-4556-8005-0c3249b8df36", "type": "business" }, "reference": "46f3ef38-22de-4498-a6d3-13749aa2a0a7", "status": "created", "successful_transfer_count": 0, "total_transfer_count": 1, "updated_at": "2024-10-02T17:39:26Z" } } ``` ```json 404 Not Found theme={null} { "error": { "code": "bulk_transfer_not_found", "message": "Bulk transfer not found", "type": "not_found_error" } } ``` ```json 401 Unauthorized theme={null} { "error": { "code": "unauthorized", "message": "Invalid or expired API key", "type": "authentication_error" } } ``` ## Status Lifecycle Bulk transfers progress through the following states: Initial state after creation * Transfers validated but not executed * Can be modified or cancelled Transfers being processed * Individual transfers updating * Cannot be modified * Can be cancelled All transfers processed * Final success/failure counts available * Cannot be modified or cancelled Manually cancelled * Incomplete transfers stopped * Cannot be restarted Past expiration date * Not executed * Cannot be modified or executed ## Error Handling * Invalid API key provided * API key expired or revoked * Missing authorization header * Insufficient permissions * API key doesn't have access * Account restrictions * Invalid bulk transfer ID * Transfer deleted * Transfer not accessible * Temporary service disruption * Retry with exponential backoff * Contact support if persistent ## Rate Limits This endpoint has the following rate limits: * 120 requests per minute per API key * Burst limit: 20 requests per second * Headers included: * X-RateLimit-Limit * X-RateLimit-Remaining * X-RateLimit-Reset ## Best Practices 1. **Monitoring** * Poll sparingly during execution * Use webhooks for status updates * Monitor failed transfers * Track execution progress 2. **Error Handling** * Implement exponential backoff * Handle rate limits gracefully * Log all request failures * Set appropriate timeouts 3. **Response Processing** * Cache stable responses * Track status changes * Monitor success rates * Alert on high failure rates For additional assistance: * Check our [Error Handling Guide](/errors) * Review [Webhook Implementation](/webhooks) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Initiate Bulk Transfer Source: https://docs.juicyway.com/transfers/bulk-transfers/initiate-bulk-transfers Create a new bulk transfer session for processing multiple transfers efficiently ## Overview Bulk transfers allow you to process multiple transfers in a single batch operation. This endpoint creates a new bulk transfer session that you can later populate with individual transfers and execute as a group. Before initiating a bulk transfer: * Ensure sufficient balance for the expected total * Have your beneficiary details ready * Review the transfer limits and cut-off times ## Endpoint ```bash theme={null} POST /bulk-transfers ``` ## Request Parameters * Maximum length: 200 characters * Used for reference and reporting Timestamp when the bulk transfer session expires * Format: ISO 8601 (e.g., "2024-10-03T18:38:31Z") * Maximum: 72 hours from creation * Default: 24 hours from creation Your unique reference for this bulk transfer * Must be unique across all bulk transfers * Maximum length: 64 characters * Alphanumeric characters, hyphens, and underscores only Additional data about the bulk transfer * Maximum size: 20KB * Key-value pairs of strings ## Request Examples ```json Basic Request theme={null} { "description": "Monthly vendor payments", "expires_at": "2024-10-03T18:38:31Z", "reference": "juice-bulk-transfer-5d906f6d-933b-4de9-927f-c7522823f5ec" } ``` ```json With Metadata theme={null} { "description": "Q4 contractor payments", "expires_at": "2024-10-03T18:38:31Z", "reference": "juice-bulk-q4-contractors-2024", "metadata": { "department": "engineering", "batch_type": "contractors", "period": "Q4-2024" } } ``` ## Response Format Created bulk transfer session details Unique identifier for the bulk transfer Creation timestamp in ISO 8601 format Expiration timestamp in ISO 8601 format Provided description Current status of the bulk transfer: * created - Initial state * executing - Transfers in progress * completed - All transfers processed * cancelled - Manually cancelled * expired - Session timeout Number of failed transfers in the batch Number of successful transfers in the batch Total number of transfers in the batch List of individual transfers (empty on creation) Additional metadata provided Details about the creating entity ## Response Examples ```json 201 Created theme={null} { "data": { "created_at": "2024-10-02T17:39:26.049258Z", "description": "Monthly vendor payments", "expires_at": "2024-10-03T18:38:31Z", "failed_transfer_count": 0, "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "items": [], "metadata": {}, "owner": { "id": "65fb1bf9-10e7-4556-8005-0c3249b8df36", "type": "personal" }, "reference": "juice-bulk-transfer-5d906f6d-933b-4de9-927f-c7522823f5ec", "status": "created", "successful_transfer_count": 0, "total_transfer_count": 0, "updated_at": "2024-10-02T17:39:26Z" } } ``` ```json 400 Invalid Request theme={null} { "error": { "code": "invalid_request", "message": "The request contains invalid parameters", "details": { "reference": ["Must be unique across all bulk transfers"] } } } ``` ```json 422 Validation Error theme={null} { "error": { "code": "validation_error", "message": "Invalid expiration time", "details": { "expires_at": ["Must be between 1 and 72 hours from now"] } } } ``` ## Validation Rules * Must be unique across all bulk transfers * Length: 1-64 characters * Allowed characters: A-Z, a-z, 0-9, -, \_ * Cannot start or end with hyphen/underscore * Must be in future * Minimum: 1 hour from creation * Maximum: 72 hours from creation * Must be valid ISO 8601 format * Maximum length: 200 characters * Cannot contain HTML or special characters * Optional but recommended for tracking * Maximum size: 20KB * Keys must be strings * Values must be strings * No nested objects allowed ## Rate Limits * 10 bulk transfer initiations per minute * Maximum of 100 transfers per batch * Burst limit: 2 requests per second ## Best Practices 1. **Reference Generation** * Use structured, meaningful references * Include date/time components * Add batch type identifiers * Store references for reconciliation 2. **Error Handling** * Implement proper retry logic * Monitor rate limits * Log all attempts * Handle timeouts gracefully 3. **Session Management** * Set reasonable expiration times * Plan for session timeouts * Monitor session status * Handle expired sessions After creating a bulk transfer session: 1. [Add transfers](/transfers/bulk-transfers/update-bulk-transfer) to the batch 2. [Execute the bulk transfer](/transfers/bulk-transfers/execute-bulk-transfer) 3. [Monitor status](/transfers/bulk-transfers/get-bulk-transfer-details) # List bulk transfers Source: https://docs.juicyway.com/transfers/bulk-transfers/list-bulk-transfers # List Bulk Transfers Retrieve a paginated list of bulk transfers with support for filtering, sorting, and status tracking. This endpoint returns all bulk transfers associated with your account in chronological order. ## Endpoint ```bash theme={null} GET /bulk-transfers ``` ## Query Parameters Filter transfers by their current status: * `created` - Initialized but not executed * `executing` - Currently processing * `cancelled` - Manually cancelled * `expired` - Past execution window * `completed` - All transfers processed Cursor for fetching next page of results * Use value from `pagination.after` in previous response Cursor for fetching previous page of results * Use value from `pagination.before` in previous response Number of records to return per page * Minimum: 1 * Maximum: 100 * Default: 10 ## Response Format Array of bulk transfer objects Unique identifier for the bulk transfer Optional description of the bulk transfer Your unique reference for the bulk transfer Current status of the bulk transfer Total number of transfers in the batch Number of successfully completed transfers Number of failed transfers ISO-8601 timestamp when the bulk transfer expires ISO-8601 timestamp of creation ISO-8601 timestamp of last update Additional metadata about the transfer Cursor for the previous page Cursor for the next page Number of records per page ## Example Request ```bash cURL theme={null} curl -X GET "https://payout-staging.spendjuice.com/v1/bulk-transfers?limit=10" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch( 'https://payout-staging.spendjuice.com/v1/bulk-transfers?limit=10', { headers: { 'Authorization': ' YOUR_API_KEY' } } ); ``` ```python Python theme={null} import requests response = requests.get( 'https://payout-staging.spendjuice.com/v1/bulk-transfers', params={'limit': 10}, headers={'Authorization': ' YOUR_API_KEY'} ) ``` ## Response Examples ```json 200 Success theme={null} { "data": [ { "created_at": "2024-10-02T17:39:26.049258", "description": "October Vendor Payments", "expires_at": "2024-10-03T17:39:25Z", "failed_transfer_count": 0, "id": "7d528558-1c20-4bb6-9a9a-a03c8292b297", "items": [], "metadata": {}, "owner": { "id": "65fb1bf9-10e7-4556-8005-0c3249b8df36", "type": "personal" }, "reference": "oct_2024_vendors", "status": "created", "successful_transfer_count": 0, "total_transfer_count": 0, "updated_at": "2024-10-02T17:39:26Z" } ], "pagination": { "after": "b101f718-d133-450c-a572-c281c7341803", "before": null, "limit": 10 } } ``` ```json 400 Invalid Parameters theme={null} { "error": { "code": "invalid_request", "message": "Invalid query parameters", "details": { "limit": ["Must be between 1 and 100"] } } } ``` ## Error Handling Occurs when: * Invalid status value provided * Limit outside allowed range * Invalid cursor format Occurs when: * Missing API key * Invalid API key * Expired API key Occurs when: * Insufficient permissions * Account restrictions ## Pagination The API uses cursor-based pagination for reliable list operations: 1. Initial request: Specify desired `limit` 2. Subsequent requests: Use the `after` cursor from previous response 3. Previous page: Use the `before` cursor if available For optimal performance: * Use reasonable page sizes (10-50 records) * Cache results when appropriate * Implement progressive loading in your UI ## Rate Limits This endpoint has the following rate limits: * 100 requests per minute per API key * Maximum of 1000 requests per hour * Burst limit: 20 requests per second ## Best Practices 1. **Efficient Filtering** * Use status filters to reduce response size * Combine filters for precise results * Cache frequently accessed data 2. **Pagination Handling** * Store cursors temporarily for navigation * Implement infinite scroll for large lists * Show loading states during fetches 3. **Error Handling** * Implement proper retry logic * Handle rate limits gracefully * Log pagination errors 4. **Performance** * Use appropriate page sizes * Cache responses when possible * Monitor API response times For additional assistance: * Check our [Error Handling Guide](/errors) * Review [Pagination Best Practices](/api-overview/pagination) * Contact [Support](mailto:support@juicyway.com) # Retry Transfer Source: https://docs.juicyway.com/transfers/bulk-transfers/retry-transfer Retry a previously failed transfer within a bulk transfer batch ## Overview The retry endpoint allows you to reattempt a failed transfer that is marked as retriable within a bulk transfer batch. This is useful when transfers fail due to temporary issues like network problems or bank system downtime. Only transfers with `retryable: true` in their status can be retried. Non-retriable failures (like invalid account numbers) cannot be retried. ## Endpoint ```bash theme={null} POST /bulk-transfers/{batch_id}/transfers/{id}/retry ``` ### Path Parameters The unique identifier of the bulk transfer batch The unique identifier of the failed transfer to retry ## Example Request ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/bulk-transfers/{batch_id}/transfers/{id}/retry" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch( `https://api.spendjuice.com/bulk-transfers/${batchId}/transfers/${transferId}/retry`, { method: 'POST', headers: { 'Authorization': ` ${apiKey}` } } ); ``` ```python Python theme={null} import requests response = requests.post( f'https://api.spendjuice.com/bulk-transfers/{batch_id}/transfers/{transfer_id}/retry', headers={'Authorization': f' {api_key}'} ) ``` ## Response Retry request accepted successfully ## Error Responses ```json theme={null} { "error": { "code": "transfer_not_found", "message": "No transfer found with the provided ID" } } ``` ```json theme={null} { "error": { "code": "not_retriable", "message": "This transfer cannot be retried" } } ``` ```json theme={null} { "error": { "code": "retry_in_progress", "message": "Transfer is already being retried" } } ``` ## Retry Limits * Maximum 3 retry attempts per transfer * 5-minute wait period between retries * 24-hour maximum retry window from initial failure * Retries count towards daily transfer limits ## Status Transitions 1. Initial failed status: `failed` with `retryable: true` 2. After retry request: `processing` 3. Final status: * Success: `succeeded` * Failure: `failed` (may be retriable again) ## Webhook Events Monitor these events for retry status: * `bulk.transfer.retry.started` - Retry attempt initiated * `bulk.transfer.retry.succeeded` - Retry completed successfully * `bulk.transfer.retry.failed` - Retry attempt failed ## Best Practices 1. **Retry Strategy** * Implement exponential backoff between retries * Track retry attempt count * Consider time of day for retries * Monitor success rates by failure reason 2. **Error Handling** * Log all retry attempts * Track retry outcomes * Handle webhook notifications * Monitor retry limits 3. **User Communication** * Notify users of retry status * Provide clear error messages * Suggest alternative actions for non-retriable failures * Set expectations for processing time For retry-related assistance: * Check our [Error Handling](/errors) guide * Contact [Support](mailto:support@juicyway.com) * Review [Webhook Events](/webhooks) # Update Bulk Transfer Source: https://docs.juicyway.com/transfers/bulk-transfers/update-bulk-transfer Add or modify transfers within an existing bulk transfer batch ## Overview The Update Bulk Transfer endpoint allows you to add transfers to an existing bulk transfer batch. Use this endpoint to populate your bulk transfer with individual payment instructions before execution. Before adding transfers: * Ensure the bulk transfer is in `created` status * Verify the batch hasn't expired * Check that you haven't exceeded maximum transfer limits ## Endpoint ```http theme={null} POST /bulk-transfers/{id}/transfers ``` ## Request Parameters The unique identifier of the bulk transfer to update Array of transfer items to add to the batch Transfer amount in smallest currency unit (e.g., cents) Beneficiary payment details Name on the beneficiary account Account number for the beneficiary Bank identifier code Name of the beneficiary bank Bank routing number (required for US transfers) Type of beneficiary account (e.g., "bank\_account") Three-letter currency code Whether to save beneficiary for future use Currency code for the source amount Currency code for the destination amount Unique reference for this transfer Description or reason for the transfer ## Example Request ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/bulk-transfers/88dbcb86-5025-4ac9-9750-4aa5a77a723c/transfers" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "items": [ { "amount": 100000, "beneficiary": { "account_name": "Rodrigo Kerluke", "account_number": "1111111111", "bank_code": "101", "bank_name": "McKenzie Bank", "routing_number": "111000038", "type": "bank_account", "currency": "USD", "save_beneficiary": true }, "destination_currency": "USD", "source_currency": "USD", "reference": "transfer-ref-001", "reason": "Monthly salary payment" } ] }' ``` ```javascript Node.js theme={null} const response = await fetch( 'https://api.spendjuice.com/bulk-transfers/88dbcb86-5025-4ac9-9750-4aa5a77a723c/transfers', { method: 'POST', headers: { 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ items: [ { amount: 100000, beneficiary: { account_name: "Rodrigo Kerluke", account_number: "1111111111", bank_code: "101", bank_name: "McKenzie Bank", routing_number: "111000038", type: "bank_account", currency: "USD", save_beneficiary: true }, destination_currency: "USD", source_currency: "USD", reference: "transfer-ref-001", reason: "Monthly salary payment" } ] }) } ); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.spendjuice.com/bulk-transfers/88dbcb86-5025-4ac9-9750-4aa5a77a723c/transfers', headers={ 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' }, json={ 'items': [{ 'amount': 100000, 'beneficiary': { 'account_name': 'Rodrigo Kerluke', 'account_number': '1111111111', 'bank_code': '101', 'bank_name': 'McKenzie Bank', 'routing_number': '111000038', 'type': 'bank_account', 'currency': 'USD', 'save_beneficiary': True }, 'destination_currency': 'USD', 'source_currency': 'USD', 'reference': 'transfer-ref-001', 'reason': 'Monthly salary payment' }] } ) ``` ## Response Format Array of created transfer items Unique identifier for the transfer ID of the parent bulk transfer Current status of the transfer: * created - Initial state * processing - Transfer in progress * completed - Successfully processed * failed - Processing failed Creation timestamp (ISO 8601) Last update timestamp (ISO 8601) Amount and currency of the transfer Converted amount and currency (if applicable) Exchange rate used (if applicable) ## Validation Rules * Maximum 100 transfers per batch * Minimum amount: \$1 equivalent * Maximum amount: Based on account tier * Must be unique within the batch * Maximum length: 64 characters * Alphanumeric characters, hyphens, and underscores only * Must be valid ISO currency codes * Source currency must match account currency * Currency conversion fees may apply ## Error Handling Bulk transfer is not in editable state * Status code: 400 * Must be in `created` status Maximum number of transfers reached * Status code: 400 * Remove existing transfers first Invalid transfer parameters * Status code: 422 * Check error details for specific fields ## Best Practices 1. **Batch Organization** * Group similar transfers together * Use consistent currencies when possible * Include clear references and descriptions * Validate beneficiary details before adding 2. **Error Management** * Implement proper error handling * Validate transfers before submission * Keep track of failed additions * Retry failed transfers with corrected data 3. **Performance** * Add transfers in reasonable batch sizes * Monitor rate limits * Handle timeouts appropriately * Log all operations After adding transfers: * [Review the bulk transfer](/transfers/bulk-transfers/get-bulk-transfer-details) * [Execute the transfers](/transfers/bulk-transfers/execute-bulk-transfer) * Monitor progress via webhooks # Transfers Overview Source: https://docs.juicyway.com/transfers/overview Initiate and manage fund transfers across multiple payment methods and currencies ## Introduction The Transfers API enables secure movement of funds between accounts using various payment methods. Whether you're sending payments to vendors, paying out to customers, or managing internal transfers, our flexible API supports both domestic and international transactions. ## Transfer Types Send money to beneficiaries: * Vendor payments * Customer refunds * Payroll disbursements * Business expenses Move funds between accounts: * Currency conversions * Balance management * Account consolidation * Settlement transfers ## Supported Payment Methods **Features** * Direct bank deposits * Real-time transfers (where available) * Automated account validation **Supported Regions** * Nigeria (NGN transfers) * Canada (Interac) **Processing Times** * NGN transfers:Almost Immediate * Interac (Canada): Almost Immediate **Transaction Limits** * NGN: ₦100 - ₦99,900,000 per transaction * CAD Interac: C5-C25,000 per transaction **Supported Tokens & Networks** * USDT: Ethereum (ETH), Tron (TRX), BNB Smart Chain (BSC) * USDC: Ethereum (ETH), Polygon (MATIC), Avalanche (AVAXC) **Features** * Multi-chain support * Low transaction fees * Fast settlement times * Cross-border capability **Processing Times** * TRX Network: 1-3 minutes (6 confirmations) * ETH Network: 5-30 minutes (12 confirmations) * MATIC Network: 1-5 minutes (15 confirmations) * AVAXC Network: 1-5 minutes (15 confirmations) **Transaction Limits** * Minimum: 10 USDT/USDC * Maximum: 100,000 USDT/USDC per transaction * Daily Limit: 500,000 USDT/USDC **Network Fees** * TRX: \~1 USDT * ETH: Variable (gas fees) * MATIC: \~0.1 USDC * AVAXC: \~0.1 USDC **Features** * Email money transfers * Real-time notifications * Automated deposits * Canadian bank support **Requirements** * Canadian bank account * Valid email/phone * Account verification **Processing Times** * Standard Transfer: 15-30 minutes * Auto-deposit: 5-15 minutes * After-hours: Next business day * Failed transfer reversals: 3-5 business days **Transaction Limits** * Minimum: C\$100 * Maximum: C\$10,000 per transaction * Daily Limit: C\$20,000 * 7-day Limit: C\$70,000 ## Currency Support & Exchange * Local bank transfers * Real-time payments * Account validation * Daily Limit: ₦100,000,000 * Interac e-Transfer * EFT payments * Wire transfers * Daily Limit: C\$100,000 ## Key Concepts ### Beneficiaries A beneficiary represents a recipient of funds. They can be: * Bank account holders * Crypto wallet addresses * Interac recipients Each beneficiary type requires specific validation: * Crypto addresses: Chain and address format validation * Interac: Email registration verification ### Transfer Flow Add and validate recipient details * Verify account/address information * Validate against destination requirements * Store beneficiary ID for future use Specify amount, currency, and purpose * Check against transfer limits * Verify sufficient balance * Include required reference information Complete any required verification * 2FA if enabled * Transfer PIN validation * Additional security checks Monitor transfer status via webhooks * Track transfer progress * Handle notifications * Process confirmations ### Transfer Status Lifecycle Transfers progress through these states: 1. `created` - Transfer initiated and validated 2. `processing` - Funds being transferred 3. `successful` - Confirmed and completed 4. `failed` - Transfer unsuccessful 5. `cancelled` - Manually or automatically cancelled Each status change triggers a webhook notification to your registered endpoint. ## Best Practices 1. **Pre-transfer Validation** * Verify beneficiary details before transfer * Check sufficient balance availability * Validate against all applicable limits * Consider currency exchange rates * Use test mode for integration 2. **Error Handling** * Implement proper retry logic * Monitor transfer status * Handle timeout scenarios * Log all transfer attempts * Process webhook notifications 3. **Security & Compliance** * Implement proper authentication * Validate webhook signatures * Monitor for suspicious patterns * Follow regulatory requirements * Maintain audit trails 4. **Rate Management** * Cache exchange rates appropriately * Handle rate expiration * Implement rate refresh logic * Show clear rate information Learn more about: * [Creating Beneficiaries](/transfers/beneficiaries/create-beneficiary) * [Initiating Transfers](/transfers/transfers/initiate-bank-transfer) * [Listing Transfers](/transfers/transfers/list-transfers) * [Error Handling](/errors) # Initiate a Stablecoin Transfer Source: https://docs.juicyway.com/transfers/transfers/initiate-a-stablecoin-transfer Send stablecoin transfers to crypto addresses with support for multiple chains ## Overview Transfer stablecoins from your Juice balance to external crypto addresses across multiple supported chains. This endpoint handles stablecoin payouts with automated rate conversion and chain validation. ## Supported Tokens and Chains **USDT Support** * Ethereum (ETH) * Tron (TRX) * BNB Smart Chain (BSC) **USDC Support** * Ethereum (ETH) * Polygon (MATIC) * Avalanche C-Chain (AVAXC) Always verify the destination chain matches the selected token to avoid lost transactions. Not all tokens are supported on all chains. ## Transaction Limits * Minimum: 10 USDT/USDC * Maximum: 50,000 USDT/USDC per transaction * Daily Limit: 100,000 USDT/USDC ## Endpoint ```bash theme={null} POST /payouts ``` ### Request Parameters Amount in minor units (e.g., 100000 = 1000.00 USD) * Minimum: 1000 (10 USD) * Maximum: 10000000 (100,000 USD) Beneficiary object ```json theme={null} "beneficiary": { "id": "", "type": "" } ``` Must be "crypto\_address" Purpose or description of the transfer * Maximum length: 140 characters Stablecoin token type * Supported values: "USDT", "USDC" Must be "USD" Unique identifier for the transfer * Must be unique across all transfers * Alphanumeric characters only Must be one of: sender, recipient\ Default: sender ### Example Request ```json theme={null} { "amount": 100000, "beneficiary": { "id": "juice-payout-5d906f6d-933b-4de9-927f-c7522823f5ec", "type": "bank_account", }, "description": "Payment for services", "destination_currency": "USDT", "pin": "123456", "reference": "juice-payout-5d906f6d-933b-4de9-927f-c7522823f5ec", "source_currency": "USD", "fee_charged_to": "sender" } ``` ### Success Response ```json theme={null} { "data": { "beneficiary": { "chain": "TRX", "address": "TRDFGhjkytywooiueonuoo", "id": "d8c0226b-048c-4c44-9606-a93333f56283", "type": "crypto_address" }, "beneficiary_type": "crypto_address", "created_at": "2024-03-01T02:29:49Z", "destination_amount": 100000, "destination_currency": "USDT", "id": "93cf071e-d773-11ee-bf78-c6d49632367b", "source_amount": 100000, "source_currency": "USD", "status": "pending", "updated_at": "2024-03-01T02:29:53Z" } } ``` ## Error Responses ```json theme={null} { "error": { "code": "invalid_request", "message": "Invalid parameters provided", "details": { "amount": ["Amount must be at least 1000"] } } } ``` ```json theme={null} { "error": { "code": "invalid_pin", "message": "Invalid authorization PIN provided" } } ``` ```json theme={null} { "error": { "code": "validation_error", "message": "The request contains invalid parameters", "details": { "destination_currency": ["Must be one of: USDT, USDC"] } } } ``` ```json theme={null} { "error": { "code": "rate_limit_exceeded", "message": "Too many requests. Please try again in 60 seconds." } } ``` ## Best Practices 1. **Chain Selection** * Use TRX for lowest fees * Consider ETH during low gas periods * Use MATIC/AVAXC for faster confirmations 2. **Error Handling** * Implement retry logic with exponential backoff * Monitor network congestion * Handle timeouts gracefully 3. **Validation** * Verify beneficiary addresses before transfer * Check sufficient balance * Validate against transfer limits 4. **Monitoring** * Track transfer status via webhooks * Monitor blockchain confirmations * Log all transfer attempts For additional assistance: * Review our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Initiate Bank Transfer Source: https://docs.juicyway.com/transfers/transfers/initiate-bank-transfer Send bank transfers to saved or new beneficiaries ## Overview Initiate bank transfers from your Juicyway balance to bank accounts. This endpoint supports both domestic and international transfers with real-time rate conversion where applicable. Before initiating a transfer: 1. Ensure sufficient balance in the source currency 2. Verify beneficiary account details 3. Confirm the charge 4. Check transfer limits for your account tier in our [Overview](/transfers/overview#processing-times) ## Charge Endpoint ```bash theme={null} GET /payouts/Charge ``` ## Request Parameters Amount to charge Cyrrency to charge e.g (USD,NGN,CAD) Cyrrency rail to use e.g (USD,NGN,CAD) ### Response ```json Response theme={null} { "data": { "can_perform": true, "fee": { "amount": 0, "currency": "string" }, "reason": "string" } } ``` `Request` # \\ Payout Endpoint ```bash theme={null} POST /payouts ``` ## Request Parameters Transfer amount in minor units (e.g., cents, kobo) * Must be within [transfer limits](/transfers/overview#processing-times) * Minimum and maximum vary by currency Beneficiary object ```json theme={null} "beneficiary": { "id": "", "type": "" } ``` Purpose or description of the transfer * Maximum length: 200 characters Currency code for the destination account * Supported: NGN, USD, CAD Your unique reference for this transfer * Must be unique across all transfers * Used for idempotency Currency to debit from your balance * Must match destination\_currency for local transfers * Rate conversion applies for cross-currency transfers Must be one of: sender, recipient\ Default: sender ## Request Examples ### Local Bank Transfer (NGN) ```json Request theme={null} { "amount": 100000, "beneficiary": { "id": "juice-payout-5d906f6d-933b-4de9-927f-c7522823f5ec", "type": "bank_account", }, "description": "Vendor Payment", "destination_currency": "NGN", "pin": "123456", "reference": "pmt_vendor_123", "source_currency": "NGN", "fee_charged_to": "sender" } ``` ```json Response theme={null} { "data": { "beneficiary": { "account_name": "ACME CORPORATION", "account_number": "0821081314", "account_type": "current", "bank_name": "ACCESS BANK", "id": "d8c0226b-048c-4c44-9606-a93333f56283", "type": "bank_account" }, "beneficiary_type": "bank_account", "created_at": "2024-03-01T02:29:49Z", "destination_amount": 100000, "destination_currency": "NGN", "id": "93cf071e-d773-11ee-bf78-c6d49632367b", "source_amount": 100000, "source_currency": "NGN", "status": "pending", "updated_at": "2024-03-01T02:29:53Z" } } ``` ### International Transfer (USD) ```json Request theme={null} { "amount": 50000, "beneficiary": { "id": "us_ben_789xyz", "type": "bank_account" }, "description": "International Payment", "destination_currency": "USD", "pin": "123456", "reference": "intl_pmt_456", "source_currency": "NGN", "fee_charged_to": "sender" } ``` ```json Response theme={null} { "data": { "beneficiary": { "account_name": "Global Services LLC", "account_number": "12345678", "routing_number": "021000021", "bank_name": "CHASE", "id": "us_ben_789xyz", "type": "bank_account" }, "beneficiary_type": "bank_account", "created_at": "2024-03-15T14:30:00Z", "destination_amount": 50000, "destination_currency": "USD", "id": "intl_tx_789abc", "source_amount": 45000000, // NGN equivalent "source_currency": "NGN", "status": "pending", "updated_at": "2024-03-15T14:30:00Z" } } ``` ## Error Handling Balance too low for transfer * Status code: 400 * Check available balance * Consider exchange rates for international transfers Invalid or inactive beneficiary * Status code: 400 * Verify beneficiary\_id * Check account status Transfer exceeds account limits * Status code: 400 * Review transfer limits * Contact support for limit increases ## Best Practices 1. **Idempotency** * Use unique references * Handle duplicate requests * Store transfer IDs 2. **Validation** * Verify account details * Check currency support * Validate amounts 3. **Monitoring** * Implement webhook handling * Track transfer status * Log all attempts 4. **Security** * Use transfer PINs * Implement 2FA where available * Monitor for suspicious patterns * Review [Transfer Limits](/transfers/overview#processing-times) * Set up [Webhook Handling](/webhooks) for transfer status updates * Learn about [Error Handling](/errors) For additional assistance: * Review our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # List Nigerian Banks Source: https://docs.juicyway.com/transfers/transfers/list-ngn-banks Retrieve a list of all supported Nigerian banks with their codes ## Overview This endpoint returns a comprehensive list of supported Nigerian banks and their corresponding codes. Use this endpoint to obtain the correct bank codes needed for bank transfers and account number resolution. Bank codes are required for: * Validating account numbers * Creating bank transfer beneficiaries * Initiating bank transfers ## Endpoint ```bash theme={null} GET /payment-methods/banks ``` ## Response Format Array of bank objects containing: Bank code required for transfers * Format: 6-digit string * Example: "000023" Official bank name * Example: "PROVIDUS BANK" ## Example Request ```bash cURL theme={null} curl -X GET "https://api.spendjuice.com/payment-methods/banks" \ -H "Authorization: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const response = await fetch('https://api.spendjuice.com/payment-methods/banks', { headers: { 'Authorization': ' YOUR_API_KEY' } }); const banks = await response.json(); ``` ```python Python theme={null} import requests response = requests.get( 'https://api.spendjuice.com/payment-methods/banks', headers={'Authorization': ' YOUR_API_KEY'} ) banks = response.json() ``` ## Example Response ```json 200 Success theme={null} { "data": [ { "code": "000014", "name": "ACCESS BANK" }, { "code": "000023", "name": "PROVIDUS BANK" }, { "code": "000013", "name": "ZENITH BANK" }, { "code": "000017", "name": "GUARANTY TRUST BANK" } ] } ``` ```json 401 Unauthorized theme={null} { "error": { "code": "unauthorized", "message": "Invalid or missing API key" } } ``` ```json 500 Server Error theme={null} { "error": { "code": "server_error", "message": "An unexpected error occurred" } } ``` ## Error Handling Indicates invalid or missing API key * Verify your API key is valid * Check authorization header format Indicates insufficient permissions * Verify your API key has correct permissions * Check your account status Indicates an internal server error * Retry the request after a short delay * Contact support if the error persists ## Usage Tips 1. **Cache Results** * Bank list changes infrequently * Cache results for up to 24 hours * Implement cache invalidation on errors 2. **Error Handling** * Implement retry logic for failed requests * Maintain a fallback bank list if needed * Log any persistent errors 3. **Data Validation** * Verify bank codes are 6 digits * Handle missing or null values * Validate against your supported banks list ## Best Practices To ensure reliable bank transfers: * Always use current bank codes * Refresh cached bank lists daily * Validate codes before transactions * Handle bank name variations * Log any unrecognized bank codes Never hardcode bank codes in your application. Always fetch them dynamically to ensure you're using the most current codes. # Resolve NGN Account Number Source: https://docs.juicyway.com/transfers/transfers/resolve-ngn-account-number Verify Nigerian bank account details before initiating payments ## Overview The account resolution endpoint allows you to validate Nigerian bank account numbers and retrieve account holder names before initiating transfers. This verification helps prevent failed transactions and ensures accurate payments. This endpoint should be called before creating beneficiaries or initiating transfers to Nigerian bank accounts. ## Endpoint ```bash theme={null} POST /payment-methods/resolve-bank-account ``` ## Request Parameters Bank account number to verify \* Must be exactly 10 digits \* Numbers only (0-9) Bank code from the [List Banks](/transfers/transfers/list-ngn-banks) endpoint * 3-6 digit identifier \* Must be for an active Nigerian bank ## Example Request ```bash cURL theme={null} curl -X POST "https://api.spendjuice.com/payment-methods/resolve-bank-account" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "account_number": "0234247896", "bank_code": "058" }' ``` ```javascript Node.js theme={null} const response = await fetch( "https://api.spendjuice.com/payment-methods/resolve-bank-account", { method: "POST", headers: { Authorization: " YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ account_number: "0234247896", bank_code: "058", }), }, ); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.spendjuice.com/payment-methods/resolve-bank-account', headers={ 'Authorization': ' YOUR_API_KEY', 'Content-Type': 'application/json' }, json={ 'account_number': '0234247896', 'bank_code': '058' } ) ``` ## Response Examples ```json 200 Success theme={null} { "data": { "account_name": "ANON NYMOUS", "account_number": "0234247896", "bank_code": "058" } } ``` ```json 400 Invalid Account Number theme={null} { "error": { "code": "invalid_account_number", "message": "Invalid account number provided", "type": "validation_error" } } ``` ```json 404 Account Not Found theme={null} { "error": { "code": "account_not_found", "message": "Account number not found for the specified bank", "type": "not_found_error" } } ``` ```json 503 Bank Unavailable theme={null} { "error": { "code": "bank_not_available", "message": "Bank resolution service temporarily unavailable", "type": "service_error" } } ``` For additional assistance: * Review our [Error Handling Guide](/errors) * Contact [support@juicyway.com](mailto:support@juicyway.com) # Add Payment Method Source: https://docs.juicyway.com/waas/add-payment-method This endpoint allows you to attach a payment method to an existing wallet. A payment method defines how funds can be added to or withdrawn from a wallet, such as via a bank account. ## Endpoint ```json theme={null} POST /wallets/{id}/payment-method ``` ## Description Use this endpoint to add a payment method to a wallet that has already been created. Once a payment method is added, the wallet can be funded or used for payouts through the specified channel. *** ## Path Parameters | Parameter | Type | Required | Description | | :-------- | :------------ | :------- | :---------------------------------- | | `id` | string (UUID) | Yes | The unique identifier of the wallet | *** ## Request Body ```json theme={null} { "type": "bank_account" } ``` ### Request Fields | Field | Type | Required | Description | | :----- | :----- | :------- | :-------------------------------- | | `type` | string | Yes | The type of payment method to add | ### Supported Payment Method Types | Type | Description | | :------------- | :-------------------------------------------------------- | | `bank_account` | Links a bank account to the wallet for funding or payouts | > Additional payment method types may be supported depending on your integration and region. *** ## Response ### Success Response (200 OK) ```json theme={null} { "data": { "id": "3d2e3f3e-3b3c-4907-a4fd-e241203440d7", "status": "active", "payment_methods": [ { "account_name": "Prosacco Erdman", "account_number": "3515200757", "account_type": "savings", "address": null, "bank_address": "9896 Bulah Roads, Suite 256, North Carolina, Kansas, 09819, US", "bank_code": "035", "bank_name": "Wema Bank" } ], "balance": { "amount": 0, "currency": "NGN" } } } ``` ## Response Fields | Field | Type | Description | | :----------------- | :----- | :------------------------------------------------- | | `id` | string | The wallet ID | | `status` | string | Current wallet status (`active`, `inactive`, etc.) | | `payment_methods` | array | List of payment methods linked to the wallet | | `balance.amount` | number | Wallet balance amount | | `balance.currency` | string | Wallet currency | > The `payment_methods` array may initially be empty if additional verification or setup is required before activation. *** ## Example cURL Request ```bash theme={null} curl -X POST https://api.yourdomain.com/wallets/{id}/payment-method \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "bank_account" }' ``` *** ## Common Errors | Status Code | Reason | | :---------- | :----------------------------------------- | | `400` | Invalid request body | | `401` | Unauthorized request | | `404` | Wallet not found | | `422` | Unsupported or invalid payment method type | *** ## Notes & Best Practices * Ensure the wallet exists and is active before adding a payment method. * Some payment methods may require additional verification steps before they become usable. * Always store and reference the wallet ID securely. * Use sandbox mode to test payment method creation before moving to production. *** ## Next Steps After successfully adding a payment method, you can: * Fund the wallet * Initiate payouts * Retrieve wallet details * Monitor wallet activity via webhooks # Additional Operations Source: https://docs.juicyway.com/waas/additional-operations This endpoint retrieves a list of wallets. You can filter results by customer, currency, or wallet status. ## Endpoint ```json theme={null} GET /wallets/all ``` ## Description Use this endpoint to fetch all wallets associated with your account. Filters can be applied to narrow results based on customer or wallet attributes. ## Query Parameters (Filters) | Parameter | Type | Description | | :------------ | :------------ | :------------------------------------------------------- | | `customer_id` | string (UUID) | Filter wallets by customer | | `currency` | string | Filter wallets by currency (e.g. `NGN`, `USD`) | | `status` | string | Filter wallets by status (`active`, `frozen`, `deleted`) | ## Example cURL Request ```bash theme={null} curl -X GET "https://api.spendjuice.com/wallets/all?currency=NGN&status=active" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" ``` *** ## Response ### Success Response (200 OK) ```json theme={null} { "data": [ { "id": "wallet_id", "customer_id": "customer_id", "currency": "NGN", "status": "active", "balance": { "amount": 1500, "currency": "NGN" } } ] } ``` *** # List Wallet Transactions This endpoint retrieves a list of wallet transactions. You can filter transactions by wallet or transaction type. *** ## Endpoint ```json theme={null} GET /wallets/transactions ``` ## Description Use this endpoint to list all transactions across wallets or to retrieve transactions for a specific wallet. ## Query Parameters (Filters) | Parameter | Type | Description | | :---------- | :------------ | :--------------------------------------------- | | `wallet_id` | string (UUID) | Filter transactions by wallet | | `type` | string | Filter by transaction type (`debit`, `credit`) | *** ## Example cURL Request ``` curl -X GET "https://api.spendjuice.com/wallets/transactions?wallet_id=wallet_id&type=debit" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" ``` ## Response ### Success Response (200 OK) ```json theme={null} { "data": [ { "id": "transaction_id", "wallet_id": "wallet_id", "type": "debit", "amount": 500, "description": "Customer payout", "created_at": "2025-07-24T10:15:30Z" } ] } ``` *** # Retrieve a Transaction This endpoint retrieves the details of a single wallet transaction by its ID. ## Endpoint ```json theme={null} GET /wallets/transactions/{id} ``` ## Description Use this endpoint to fetch full details of a specific transaction, including amount, type, and timestamps. ## Path Parameters | Parameter | Type | Required | Description | | :-------- | :------------ | :------- | :---------------------------- | | `id` | string (UUID) | Yes | Unique transaction identifier | ## Example cURL Request ```bash theme={null} curl -X GET "https://api.spendjuice.com/wallets/transactions/{id}" \ -H "Authorization: YOUR_API_KEY" \ -H "Content-Type: application/json" ``` ## Response ### Success Response (200 OK) ```json theme={null} { "data": { "id": "transaction_id", "wallet_id": "wallet_id", "type": "credit", "amount": 1000, "description": "Wallet top-up", "created_at": "2025-07-24T09:45:00Z" } } ``` *** ## Common Errors | Status Code | Description | | :---------- | :------------------------- | | `401` | Unauthorized | | `404` | Resource not found | | `400` | Invalid request parameters | *** ## Notes & Best Practices * Use filters to reduce payload size and improve performance. * Always verify wallet status before initiating related actions. * Paginate responses if supported to handle large result sets. * Use transaction IDs for reconciliation and audit purposes. # Create Customer Source: https://docs.juicyway.com/waas/create-customer Before creating a wallet, you must first create a customer. A customer can be an individual or a business and represents the entity that owns one or more wallets. ## Endpoint ```json theme={null} POST /customers ``` ## Description This endpoint provisions a customer in the system. The customer record is required to associate wallets, transactions, and payment methods. After creation, the customer typically starts in a `pending_kyc` status until verification is completed. ## Request Body ```json theme={null} { "first_name": "James", "last_name": "Okafor", "email": "james.okafor@example.com", "phone": "+2348012345678", "type": "individual", "billing_address": { "line1": "123 Test Lane", "line2": "Suite 456", "city": "Lagos", "state": "Lagos", "zip_code": "100001", "country": "NG" } } ``` *** ## Request Fields | Field | Type | Required | Description | | :---------------- | :----- | :------- | :------------------------------------------ | | `first_name` | string | Yes | Customer’s first name | | `last_name` | string | Yes | Customer’s last name | | `email` | string | Yes | Customer’s email address | | `phone` | string | Yes | Customer’s phone number (with country code) | | `type` | string | Yes | Customer type: `individual` or `business` | | `billing_address` | object | Yes | Customer’s billing address | ### Billing Address Fields | Field | Type | Required | Description | | :--------- | :----- | :------- | :------------------------ | | `line1` | string | Yes | Street address line 1 | | `line2` | string | No | Street address line 2 | | `city` | string | Yes | City | | `state` | string | Yes | State or region | | `zip_code` | string | Yes | Postal code | | `country` | string | Yes | ISO 2-letter country code | *** ## Response ### Success Response (201 Created) ``` { "data": { "id": "7da75a46-a1bc-11ee-9a32-560f156a658b", "status": "pending_kyc", "created_at": "2025-09-22T09:01:09Z" } } ``` *** ## Response Fields | Field | Type | Description | | :----------- | :----- | :---------------------------------------------- | | `id` | string | Unique customer identifier | | `status` | string | Customer status (`pending_kyc`, `active`, etc.) | | `created_at` | string | Timestamp when the customer was created | *** ## Example cURL Request ```bash theme={null} curl -X POST https://api.yourdomain.com/customers \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "first_name": "James", "last_name": "Okafor", "email": "james.okafor@example.com", "phone": "+2348012345678", "type": "individual", "billing_address": { "line1": "123 Test Lane", "line2": "Suite 456", "city": "Lagos", "state": "Lagos", "zip_code": "100001", "country": "NG" } }' ``` *** ## Common Errors | Status Code | Description | | :---------- | :----------------------------------------- | | `400` | Invalid request or missing required fields | | `401` | Unauthorized | | `409` | Customer already exists | | `422` | Invalid field values | *** ## Notes & Best Practices * Ensure all mandatory fields are provided and formatted correctly. * The `status` starts as `pending_kyc` if verification is required. * Store the returned `id` as it is needed to create wallets and associate transactions. * Validate emails and phone numbers to prevent errors in subsequent wallet creation. *** ## Typical Flow 1. Create a customer via `POST /customers`. 2. Verify customer if required (KYC). 3. Create a wallet for the customer using `POST /wallets`. 4. Add payment methods and perform transactions as needed. # Create Wallet Source: https://docs.juicyway.com/waas/create-wallet This endpoint allows you to create a new wallet for a specific customer in a chosen currency. Each wallet is linked to a customer and can be used to manage balances, transactions, and payment methods. ## Endpoint ```json theme={null} POST /wallets ``` ## Description Use this endpoint to provision a wallet for a customer. The wallet is automatically assigned a unique ID and starts with a **zero balance**. The wallet status is set to `active` upon creation. *** ## Request Body ```json theme={null} { "currency": "NGN", "customer_id": "7da75a46-a1bc-11ee-9a32-560f156a658b" } ``` *** ## Request Fields | Field | Type | Required | Description | | :------------ | :------------ | :------- | :------------------------------------------------ | | `customer_id` | string (UUID) | Yes | The customer for whom the wallet is being created | | `currency` | string | Yes | The currency for the wallet (e.g., `NGN`, `USD`) | *** ## Response ### Success Response (201 Created) ```json theme={null} { "data": { "id": "3d2e3f3e-3b3c-4907-a4fd-e241203440d7", "account_id": "f55ca88c-71aa-4dab-a10a-4d818c11e8e6", "customer_id": "a08bf5a3-8459-4e65-a5bb-34a1feef94cf", "balance": { "amount": 0, "currency": "NGN" }, "status": "active" } } ``` *** ## Response Fields | Field | Type | Description | | :----------------- | :----- | :-------------------------------------- | | `id` | string | Unique wallet ID | | `account_id` | string | Internal account identifier | | `customer_id` | string | ID of the customer linked to the wallet | | `balance.amount` | number | Current wallet balance (starts at 0) | | `balance.currency` | string | Currency of the wallet | | `status` | string | Wallet status (`active`) | *** ## Example cURL Request ```bash theme={null} curl -X POST https://api.yourdomain.com/wallets \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "currency": "NGN", "customer_id": "7da75a46-a1bc-11ee-9a32-560f156a658b" }' ``` *** ## Common Errors | Status Code | Description | | :---------- | :--------------------------------------------------- | | `400` | Invalid request or unsupported currency | | `401` | Unauthorized | | `404` | Customer not found | | `409` | Wallet already exists for this customer and currency | *** ## Notes & Best Practices * Ensure the customer exists before creating a wallet. * Only create one wallet per customer per currency to avoid duplicates. * The wallet starts with a zero balance and `active` status. * Use the wallet `id` for all subsequent transactions, payment methods, or status updates. *** ## Common Use Cases * Provision wallets when a new customer signs up * Enable multi-currency wallet management for existing customers * Prepare wallets for payouts, funding, or transaction processing # Overview Source: https://docs.juicyway.com/waas/overview The Juicyway Wallet API enables businesses to programmatically create and manage customer wallets, fund wallets, and process payouts across supported currencies. This guide describes the required endpoints, request/response formats, and recommended integration flow for Wallet-as-a-Service (WaaS). ## Wallet-as-a-Service (WaaS) Wallet-as-a-Service (WaaS) provides an API-driven abstraction for wallet creation, funding, payouts, and transaction tracking. WaaS handles: * Wallet lifecycle management * Multi-currency balances * Credit and debit transactions * Wallet status controls * Transaction reconciliation *** ## Core Features & APIs The Wallet API supports the following operations: * **Customer Management** * Create and manage customer profiles * **Wallet Management** * Create wallets per customer and currency * Retrieve wallet details and balances * Update wallet status (active, frozen, deleted) * **Payment Methods** * Add supported payment methods to wallets * **Transactions** * Credit transactions (funding) * Debit transactions (payouts) * Transaction listing and retrieval *** ## Base URL ``` https://api.spendjuice.com ``` *** ## Authentication All API requests require authentication using an API key. **Header** ``` Authorization: YOUR_API_KEY ``` ## Typical Merchant Flow ### Customer Onboarding 1. Create customer 2. Complete KYC verification 3. Create wallet 4. Add payment method ### Daily Operations * Fund wallet (credit) * Process payouts (debit) * Retrieve balances * Monitor transactions ### Account Management * Freeze wallet ```json theme={null} PATCH /wallets/{id}/status ``` * Delete wallet ```json theme={null} PATCH /wallets/{id}/status ``` *** ## Error Handling | Code | Description | | :--- | :------------------------------ | | 400 | Invalid request parameters | | 401 | Unauthorized (invalid API key) | | 404 | Resource not found | | 422 | Business rule validation failed | | 500 | Internal server error | ## Best Practices * Complete customer KYC before wallet activation. * Use idempotency keys for wallet and transaction creation. * Persist transaction IDs for reconciliation. * Keep wallet status synchronized with internal user state. * Use sandbox mode before production deployment. # Update wallet balance Source: https://docs.juicyway.com/waas/process-payout This endpoint is used to debit or credit a wallet balance. It supports internal wallet adjustments such as payouts, refunds, top-ups, or manual balance corrections. ## Endpoint ```json theme={null} POST /wallets/transactions ``` ## Description Use this endpoint to create a transaction that either **adds funds to a wallet (credit)** or **removes funds from a wallet (debit)**. The wallet balance is updated immediately upon successful processing. ## Request Body ```json theme={null} { "amount": 500, "description": "Customer payout", "type": "debit", "wallet_id": "3d2e3f3e-3b3c-4907-a4fd-e241203440d7" } ``` *** ## Request Fields | Field | Type | Required | Description | | :------------ | :------------ | :------- | :-------------------------------------- | | `wallet_id` | string (UUID) | Yes | Wallet to be debited or credited | | `amount` | number | Yes | Transaction amount (in wallet currency) | | `type` | string | Yes | Transaction type: `debit` or `credit` | | `description` | string | No | Reason or note for the transaction | *** ## Supported Transaction Types | Type | Description | | :------- | :------------------------------------ | | `credit` | Adds funds to the wallet balance | | `debit` | Removes funds from the wallet balance | *** ## Response ### Success Response (200 OK) ```json theme={null} { "data": { "transaction_id": "transaction_id", "wallet_id": "wallet_id", "type": "debit", "amount": 500, "balance_after": 1500, "created_at": "2025-07-24T10:15:30Z" } } ``` *** ## Common Errors | Status Code | Description | | :---------- | :----------------------------- | | `400` | Invalid request | | `401` | Unauthorized | | `404` | Wallet not found | | `409` | Insufficient balance for debit | | `422` | Invalid transaction type | *** ## Notes & Best Practices * Ensure the wallet is **active** before initiating a transaction. * Debits will fail if the wallet balance is insufficient. * Use clear and descriptive transaction descriptions for auditing. * Avoid using this endpoint for external payments; use dedicated payout or funding endpoints instead. *** ## Common Use Cases * Customer payouts * Refunds * Wallet top-ups * Internal balance adjustments # Retrieve Wallet Source: https://docs.juicyway.com/waas/retrieve-wallet This endpoint retrieves the full details of a wallet, including its balance, status, linked payment methods, and historical events. It is commonly used to display wallet information, verify wallet state, and support operational or compliance workflows. ## Endpoint ```json theme={null} GET /wallets/{id} ``` ## Description Use this endpoint to fetch the current state of a wallet. The response includes balance information, associated customer and account IDs, payment methods, wallet status, and lifecycle events. ## Path Parameters | Parameter | Type | Required | Description | | :-------- | :------------ | :------- | :------------------------------ | | `id` | string (UUID) | Yes | Unique identifier of the wallet | ## Response ### Success Response (200 OK) ```json theme={null} { "data": { "account_id": "f55ca88c-71aa-4dab-a10a-4d818c11e8e6", "balance": { "amount": 0, "currency": "USD" }, "customer_id": "a08bf5a3-8459-4e65-a5bb-34a1feef94cf", "events": [ { "action": "create", "id": "6a2a5833-609d-4dff-a4e6-0eaf452d7826", "inserted_at": "2025-07-24T08:08:07Z", "reason": null, "wallet_id": "55a76a42-ed3a-4d0b-b74c-2887d64612f6" } ], "id": "3d2e3f3e-3b3c-4907-a4fd-e241203440d7", "payment_methods": [ { "account_name": "Prosacco Erdman", "account_number": "3515200757", "account_type": "savings", "address": null, "bank_address": "9896 Bulah Roads, Suite 256, North Carolina, Kansas, 09819, US", "bank_code": "035", "bank_name": "Wema Bank" } ], "status": "active" } } ``` *** ## Response Fields ### Wallet Information | Field | Type | Description | | :------------ | :----- | :---------------------------------- | | `id` | string | Wallet ID | | `status` | string | Current wallet status | | `customer_id` | string | Customer associated with the wallet | | `account_id` | string | Internal account identifier | *** ### Balance | Field | Type | Description | | :----------------- | :----- | :--------------------- | | `balance.amount` | number | Current wallet balance | | `balance.currency` | string | Wallet currency | *** ### Payment Methods | Field | Type | Description | | :---------------- | :----- | :-------------------------------------------- | | `payment_methods` | array | List of payment methods linked to the wallet | | `account_name` | string | Name on the bank account | | `account_number` | string | Bank account number | | `account_type` | string | Type of bank account (e.g., savings, current) | | `bank_name` | string | Name of the bank | | `bank_code` | string | Bank routing or institution code | | `bank_address` | string | Bank branch address | > Sensitive fields may be partially masked depending on environment and permissions. *** ### Events | Field | Type | Description | | :------------ | :---------------- | :---------------------------------------------- | | `events` | array | Historical actions performed on the wallet | | `action` | string | Event type (e.g., `create`, `freeze`, `delete`) | | `inserted_at` | string (ISO 8601) | Timestamp of the event | | `reason` | string | Reason for the action, if provided | *** ## Example cURL Request ```bash theme={null} curl -X GET https://api.yourdomain.com/wallets/{id} \ -H "Authorization: Bearer YOUR_API_KEY" ``` *** ## Common Errors | Status Code | Description | | :---------- | :--------------- | | `401` | Unauthorized | | `404` | Wallet not found | | `403` | Access denied | *** ## Use Cases * Display wallet details in a dashboard * Check wallet balance and status before transactions * Review linked payment methods * Audit wallet activity and lifecycle events *** ## Notes & Best Practices * Always confirm wallet status before initiating funding or payouts. * Cache wallet responses carefully to avoid stale balance data. * Use wallet events for audit logs and compliance reviews. # Update Wallet Status Source: https://docs.juicyway.com/waas/update-wallet-status This endpoint allows you to update the operational status of an existing wallet. Wallet status controls whether the wallet can be used for transactions and helps enforce risk, compliance, and lifecycle management rules. ## Endpoint ```json theme={null} PATCH /wallets/{id}/status ``` ## Description Use this endpoint to change the status of a wallet to **active**, **frozen**, or **deleted**.\ Status updates are commonly used to temporarily restrict wallet activity, permanently disable a wallet, or re-enable it after review. ## Path Parameters | Parameter | Type | Required | Description | | :-------- | :------------ | :------- | :------------------------------ | | `id` | string (UUID) | Yes | Unique identifier of the wallet | *** ## Request Body ``` { "status": "frozen", "reason": "Suspicious activity detected" } ``` *** ## Request Fields | Field | Type | Required | Description | | :------- | :----- | :------- | :----------------------------------------------------------------------- | | `status` | string | Yes | New status to apply to the wallet | | `reason` | string | No | Explanation for the status change (recommended for audit and compliance) | *** ## Supported Statuses | Status | Description | | :-------- | :------------------------------------------------------- | | `active` | Wallet is enabled and can perform transactions | | `frozen` | Wallet is temporarily disabled; transactions are blocked | | `deleted` | Wallet is permanently disabled and cannot be reactivated | *** ## Response ### Success Response (200 OK) ``` { "data": { "id": "wallet_id", "status": "frozen" } } ``` *** ## Response Fields | Field | Type | Description | | :------- | :----- | :-------------------- | | `id` | string | Wallet identifier | | `status` | string | Updated wallet status | *** ## Example cURL Request ``` curl -X PATCH https://api.yourdomain.com/wallets/{id}/status \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": "frozen", "reason": "Suspicious activity detected" }' ``` *** ## Common Errors | Status Code | Reason | | :---------- | :------------------------ | | `400` | Invalid status value | | `401` | Unauthorized request | | `404` | Wallet not found | | `422` | Invalid status transition | *** ## Status Transition Rules (Recommended) * `active` → `frozen` ✅ * `frozen` → `active` ✅ * `active` → `deleted` ✅ * `frozen` → `deleted` ✅ * `deleted` → any status ❌ (not allowed) *** ## Notes & Best Practices * Always include a `reason` when freezing or deleting a wallet for audit and compliance purposes. * Freezing a wallet should immediately block: * Incoming transfers * Outgoing transfers * Payment method usage * Deleting a wallet should be treated as irreversible. * Log all status changes for traceability and risk monitoring. *** ## Common Use Cases * **Freeze wallet** due to suspicious or fraudulent activity * **Reactivate wallet** after compliance review * **Delete wallet** when a customer account is closed *** ## Next Steps After updating a wallet’s status, you may want to: * Notify the user of the status change * Review transaction history * Trigger internal compliance or risk workflows # Webhooks Source: https://docs.juicyway.com/webhooks Integration Guide for Webhook Events Before integrating webhooks, make sure you've completed the [Quickstart](/quickstart) guide and have your authentication set up. ## Overview When you make a request to our API, you'll typically get an immediate response. However, some operations like payments can take time to process. Instead of timing out, we return a pending status and use webhooks to notify you of the final result. You have two options for handling these async operations: * Poll the API endpoints periodically (not recommended for production) * **Use webhooks to receive real-time event updates (recommended)** ### Webhooks vs Polling * Make repeated GET requests to check transaction status - Higher latency and more resource intensive - May miss state changes between polls - Better suited for testing/debugging * Receive instant notifications when state changes - More efficient and scalable - No missed events - Recommended for production use ## Setting Up Webhooks ### 1. Create Your Webhook URL Create a POST endpoint on your server to receive webhook events. The endpoint should: 1. Accept JSON payloads 2. Return a 200 OK response 3. Process events idempotently (handle duplicates safely) ```python Python theme={null} theme={null} theme={null} from flask import Flask, request import hmac import hashlib import json app = Flask(__name__) def validate_signature(payload, checksum, business_id): # Separate event and data event = payload['event'] data = json.dumps(payload['data']) message = f"{event}|{data}" # Create HMAC SHA256 hash expected = hmac.new( business_id.encode('utf-8'), message.encode('utf-8'), hashlib.sha256 ).hexdigest().upper() return hmac.compare_digest(expected, checksum) @app.route('/webhook', methods=['POST']) def handle_webhook(): payload = request.json checksum = payload.get('checksum') business_id = 'YOUR_BUSINESS_ID' # Validate webhook signature if not validate_signature(payload, checksum, business_id): return 'Invalid signature', 401 # Process the webhook event event_type = payload.get('event') if event_type == 'payment.session.succeeded': handle_successful_payment(payload['data']) elif event_type == 'payment.session.failed': handle_failed_payment(payload['data']) # Return 200 to acknowledge receipt return 'Webhook received', 200 ``` ```javascript Node.js theme={null} theme={null} theme={null} import crypto from "crypto"; import express from "express"; import stringify from "json-stable-stringify"; const app = express(); app.use(express.json()); function validateSignature(payload, checksum, businessId) { const { event, data } = payload; const stringData = JSON.stringify(data); const message = `${event}|${stringData}`; // Create HMAC SHA256 hash const expectedChecksum = crypto .createHmac("sha256", businessId) .update(message) .digest("hex") .toUpperCase(); return crypto.timingSafeEqual( Buffer.from(expectedChecksum), Buffer.from(checksum), ); } app.post("/webhook", (req, res) => { const payload = req.body; const checksum = payload.checksum; const businessId = "YOUR_BUSINESS_ID"; // Validate webhook signature if (!validateSignature(payload, checksum, businessId)) { return res.status(401).send("Invalid signature"); } // Process webhook event const eventType = payload.event; switch (eventType) { case "payment.session.succeeded": handleSuccessfulPayment(payload.data); break; case "payment.session.failed": handleFailedPayment(payload.data); break; } // Acknowledge receipt res.status(200).send("Webhook received"); }); ``` ```php PHP theme={null} theme={null} theme={null} event; $data = json_encode($payload->data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $message = $event . '|' . $data; $expected = strtolower(hash_hmac('sha256', $message, $business_id)); $checksum = strtolower($checksum); return hash_equals($expected, $checksum); } $data = file_get_contents('php://input'); $payload = json_decode($data); $checksum = $payload->checksum; $business_id = ''; // Validate webhook signature if (!validate_signature($payload, $checksum, $business_id)) { http_response_code(401); echo 'Invalid signature' . "\n"; exit; } // Process webhook event $eventType = $payload->event; switch($eventType) { case 'payment.session.succeeded': handleSuccessfulPayment($payload->data->); break; case 'payment.session.failed': handleFailedPayment($payload->data); break; } // Acknowledge receipt http_response_code(200); echo 'Webhook received'; ``` ### 2. Register Your Webhook URL Add your webhook URL to your account settings: ```bash theme={null} PATCH /accounts/settings ``` ```json Request theme={null} { "webhook_urls": ["https://your-domain.com/webhooks"] } ``` ```json Response theme={null} { "data": { "settings": { "webhook_urls": ["https://your-domain.com/webhooks"] } } } ``` ## Security **Important Security Considerations:** * Never expose sensitive credentials in client-side code or VCS * Always validate request signatures and origins * Use HTTPS for all API communications * Implement proper access control and authentication * Follow secure key management practices **Never Share or Expose:** * API Keys * Secret Keys * Encryption Keys * Webhook Secrets * Authentication Tokens **Key Security Measures:** 1. Store sensitive data in secure environment variables or dedicated key management systems 2. Implement IP whitelisting where possible 3. Validate all incoming webhook signatures 4. Use strong TLS/SSL for all connections 5. Rotate credentials regularly 6. Log and monitor access attempts 7. Follow the principle of least privilege **Implementation Tips:** ```javascript theme={null} theme={null} theme={null} // ❌ Avoid hardcoding secrets const apiKey = "sk_live_123..."; // Bad practice // ✅ Use environment variables const apiKey = process.env.API_KEY; // Good practice // ✅ Validate webhook signatures const isValidSignature = verifyWebhookSignature( payload, signature, webhookSecret, ); ``` For additional security best practices, refer to our Security Guidelines in the documentation. ### Verifying Webhook Origins Secure your webhook endpoint using either or both: #### 1. Checksum Validation Each webhook includes a checksum for verification: ```json theme={null} { "checksum": "32762AE880695AE7343A649CB9C36CA6FF83AA258A139804AEF7D73B421DE097", "data": { "card_id": "81817411-9ffd-42ba-8bc8-f407b5cef9d9", "amount": 1000, "reference": "b070b0d2-e394-4783-a6f0-f10ccb3cae89", "currency": "USD" }, "event": "card.transaction" } ``` To validate: 1. Concatenate: `event|json_encoded_data` 2. Create HMAC SHA-256 hash using your business ID as the key 3. Compare with the received checksum The encoded data must exclude the checksum field and be in alphabetical order: ```json Valid Order theme={null} { "amount": 1000, "card_id": "81817411-9ffd-42ba-8bc8-f407b5cef9d9", "currency": "USD", "reference": "b070b0d2-e394-4783-a6f0-f10ccb3cae89" } ``` #### 2. IP Whitelisting Whitelist these Juicyway IPs: ```bash theme={null} 104.248.130.0 104.248.136.223 142.93.166.85 142.93.170.65 159.65.121.43 165.22.78.88 209.38.217.122 209.38.227.232 46.101.179.170 46.101.190.207 64.226.91.150 167.172.97.202 ``` ## Go-Live Checklist Ensure your webhook URL is publicly accessible (no localhost) Add trailing `/` if using .htaccess Verify JSON parsing and 200 OK responses Return 200 OK before processing lengthy operations Track non-200 responses in your logs Handle duplicate events safely ## Supported Events In sandbox, successful transactions remain pending. Only failure events are sent. ### Payment Events ```json theme={null} { "checksum": "", "data": { "amount": 10000, "callback_urls": {}, "cancellation_reason": null, "channel_reference": "", "collection_mode": null, "correlation_id": "", "currency": "NGN", "customer": { "account_id": "", "billing_address": { "city": "", "country": "NG", "line1": "", "state": "", "zip_code": "" }, "email": "", "first_name": "", "id": "", "last_name": "", "phone_number": "", "type": "" }, "date": "", "description": "", "fee": null, "id": "", "merchant": { "address": { "city": "", "country": "NG", "line1": "", "line2": null, "state": "", "zip_code": "" }, "email": "", "id": "", "mcc": "", "name": "", "phone": "" }, "order": { "identifier": "", "items": [ { "name": "Transfer", "type": "digital" } ] } "mode": "live", "order": { "identifier": "", "items": [ { "name": "Transfer", "type": "digital" } ] }, "payer": { "account_name": null, "account_number": null, "bank_name": "" }, "payment_method": { "account_numner": "", "account_name": "", "bank_code": "", "bank_name": "", "currency": "", "id": "", "type": "bank_account" }, "provider_id": "", "redirect_url": null, "reference": "", "status": "success|failed", "transaction_id": "", "type": "payin|payout" }, "event": "payment.session.succeeded|payment.session.failed" } ``` * Learn about [API Request Authentication](/authentication) - Review common [Error Handling](/errors) - Explore the full [API Reference](/api-reference/overview) ``` ```